#はじめに
PCとスマホの両方にレスポンシブで対応しないといけないが、スマホのみでタブメニューを表示させたい場合にご参考ください。
React(TypeScript), Material-UIで開発しています。
#やりたいこと
- PCではGridを使い縦3列にコンポーネントを配置したい
- スマホでは、3つのコンポーネントのどれを表示するか選択できるタブを表示させたい
- スマホでは、タブの選択で動的にコンポーネントを1つずつ表示させたい
#方針
- Material-UIのTabを利用する
- State変数を配列で宣言し、スマホとPCで設定する初期値を変える
- Tabの選択で、それぞれの数字を配列に入れる
- 変数がそれぞれの数字を持っているかいないかで、表示を出し分ける
#実装
###1.UseStateで宣言
スマホの表示幅を600px未満とし、window.innnerWidth
で判定する。Material-UIのGridが600px未満でxsと定義されているため同様にした。PCサイズの場合は、valueTabs
に1,2,3の数字を初期値として入れる。スマホサイズの場合は1のみを初期値として入れる。
const [valueTabs, setValueTabs] = useState(window.innerWidth > 600 ? [1,2,3] : [1])
const handleChangeTabs = (event: React.ChangeEvent<{}>, newValue: number) => {
setValueTabs([newValue])
};
###2.タブの作成
スマホのみで表示させるため、<Hidden smUP>
とする。変数valueTabs
は配列のため、配列の一番最初の値のみをvalue
に入れる。
<Hidden smUp>
<Tabs
value={valueTabs[0]}
onChange={handleChangeTabs}
aria-label="ant example"
variant="fullWidth"
>
<Tab value={1} label="Tab1" />
<Tab value={2} label="Tab2" />
<Tab value={3} label="Tab3" />
</Tabs>
</Hidden>
###3. コンポーネントの表示の出し分け
someメソッド
を使い、配列の中の特定の値があるかどうかを判定する。 &&条件
を使い、条件がtrue
の場合にのみ中身を表示をさせる。Grid item
で、PCの場合は3分割( sm={4}
)、スマホの場合は全画面表示( xd={12}
)を行う。
{valueTabs.some((a) => a == 1) &&(
<Grid item xs={12} sm={4} >
//ここにコンポーネント1の中身を記述
</Grid>
)}
#完成
import {Tabs,Tab,Hidden,Grid} from "@material-ui/core"
const [valueTabs, setValueTabs] = useState(window.innerWidth > 600 ? [1,2,3] : [1])
const handleChangeTabs = (event: React.ChangeEvent<{}>, newValue: number) => {
setValueTabs([newValue])
};
return (
<Hidden smUp>
<Tabs
value={valueTabs[0]}
onChange={handleChangeTabs}
aria-label="ant example"
variant="fullWidth"
>
<Tab value={1} label="Tab1" />
<Tab value={2} label="Tab2" />
<Tab value={3} label="Tab3" />
</Tabs>
</Hidden>
<Grid container alignItems="stretch" >
{valueTabs.some((a) => a == 1) &&(
<Grid item xs={12} sm={4} >
//ここにコンポーネント1の中身を記述
</Grid>
)}
{valueTabs.some((a) => a == 2) &&(
<Grid item xs={12} sm={4} >
//ここにコンポーネント2の中身を記述
</Grid>
)}
{valueTabs.some((a) => a == 3) &&(
<Grid item xs={12} sm={4} >
//ここにコンポーネント3の中身を記述
</Grid>
)}
</Grid>
)
タブを表示させ、中身を出し分けること自体はMaterial UIの公式サイトの内容で十分ですが、PCではタブを表示させずスマホでのみ表示させたいという場合にあまり参考になる記事が見つからず時間がかかりました。 変数を配列にし、各コンポーネントに該当する数字があるかないかで判断することで、一定シンプルに書くことができました。
#参考