こんにちは。株式会社インプルの下地です。
今回は、ReactでSwiper + MUI Tab を利用してスワイプでタブ切り替えをする方法について簡単に紹介します。なお備忘録として書くためメモ書きのような形です。あらかじめご了承ください。
イメージとしては以下の動きを実現させます。
SwiperとMUIのインストール
Create React Appでプロジェクトを作成します。
プロジェクト名はswiper-tab-appで作成します。
$ npx create-react-app swiper-tab-app
$ cd swiper-tab-app
$ npm start
次にSwiperをインストールします。
$ npm install swiper
最後にMUIをインストールします。
$ npm install @mui/material @emotion/react @emotion/styled
実装
まずはSwiperを表示させます。
SwiperTab.jsというコンポーネントを作成し、Swiperを表示させます。
Swiper React Components
Swiper is the most modern free mobile touch slider with hardware accelerated transitions and amazing native behavior.
// Import Swiper React components
import { Swiper, SwiperSlide } from 'swiper/react';
// Import Swiper styles
import 'swiper/css';
export const SwiperTab = () => {
return (
<Swiper
spaceBetween={50}
slidesPerView={1}
onSlideChange={() => console.log('slide change')}
onSwiper={(swiper) => console.log(swiper)}
>
<SwiperSlide>Slide 1</SwiperSlide>
<SwiperSlide>Slide 2</SwiperSlide>
<SwiperSlide>Slide 3</SwiperSlide>
</Swiper>
);
};
次にMUIのTabを表示させます。
React Tabs component - Material UI
Tabs make it easy to explore and switch between different views.
import Box from '@mui/material/Box';
import Tabs from '@mui/material/Tabs';
import Tab from '@mui/material/Tab';
const [value, setValue] = useState(0);
const handleChange = (event, newValue) => {
setValue(newValue);
}
<Box sx={{ width: '100%', bgcolor: 'background.paper' }}>
<Tabs value={value} onChange={handleChange} centered>
<Tab label="Item One" />
<Tab label="Item Two" />
<Tab label="Item Three" />
</Tabs>
</Box>
このままでは、SwiperとTabが独立しているため連動させます。
連動させるためには、swiperで表示させるスライドの値とTabのアクティブになっている値を同じにする必要があります。
import { useState } from "react";
// Import Swiper React components
import { Swiper, SwiperSlide } from "swiper/react";
// Import Swiper styles
import "swiper/css";
import Box from "@mui/material/Box";
import Tabs from "@mui/material/Tabs";
import Tab from "@mui/material/Tab";
export const SwiperTab = () => {
const [swiper, setSwiper] = useState(null);
const [value, setValue] = useState(0);
const slideChange = (index) => {
setValue(index);
};
const tabChange = (event, newValue) => {
setValue(newValue);
swiper.slideTo(newValue);
};
return (
<>
<Swiper
spaceBetween={50}
slidesPerView={1}
onSlideChange={(index) => slideChange(index.activeIndex)}
onSwiper={(swiper) => {
const swiperInstance = swiper;
setSwiper(swiperInstance);
}}
>
<SwiperSlide>Slide 1</SwiperSlide>
<SwiperSlide>Slide 2</SwiperSlide>
<SwiperSlide>Slide 3</SwiperSlide>
</Swiper>
<Box sx={{ width: "100%", bgcolor: "background.paper" }}>
<Tabs value={value} onChange={tabChange} centered>
<Tab label="Item One" value={0} />
<Tab label="Item Two" value={1} />
<Tab label="Item Three" value={2} />
</Tabs>
</Box>
</>
);
};
完成形がこちら。
まとめ
onSwiperがSwiperのインスタンスを受け取るコールバックであることを発見できずに苦労したので、同じ悩みを持っている人の一助になれば幸いです。
あんまり綺麗なコードではない(気がする)ので、もっとこうした方がいいとかあれば教えて欲しいです。
ここまで読んで頂きありがとうございました!
参考
Getting Started With Swiper
Swiper is the most modern free mobile touch slider with hardware accelerated transitions and amazing native behavior.
Installation - Material UI
Install Material UI, the world's most popular React UI framework.