React でスワイプによるスライドの操作を実装するライブラリ react-swipeable-views が非推奨になりました。この記事では、MUI (旧 Material-UI) のドキュメントに掲載されている react-swipeable-views を使ったコードを代替するライブラリ Swiper に置き換えていきます。
先行記事
【React】Swiper + MUI Tab を利用してスワイプでタブ切り替えを行う
https://ramble.impl.co.jp/1959/
本記事では以上の記事を大いに参考にしていますが、以下の2点で異なります。
- TypeScript で記述
- react-swipeable-views からの移行を念頭に置いて、その差分を記述
react-swipeable-views
react-swipeable-views は React でスワイプ動作を実装するライブラリです。
MUI (Material-UI) の Tabs のデモで紹介されているように React でスワイプを実装するメジャーなライブラリですが、新たなメンテナーが見つからず、2022年10月に非推奨であることが開発者によって明言されました。
Deprecate package, do not use #676
https://github.com/oliviertassinari/react-swipeable-views/issues/676
Swiper
Swiper は元々ピュア JavaScript でスワイプ動作を実装するライブラリでしたが、2020年7月にリリースされた v6 から React に対応し、その後のリリースで Vue や Angular にも対応しています。また TypeScript 製なので型定義ファイルが含まれています。
Swiper React の基本的な使い方
|
|
|
|
<Swiper>
と <SwiperSlide>
の2種類のコンポーネントと swiper/css
をインポートすることで Swiper を React で使用することができます。
<Swiper>
コンポーネントが Swiper のインスタンス(以降 SwiperCore
と表記)を生成し、コンポーネント内部でステートを保持する仕組みになっています。
Swiper React Components
https://swiperjs.com/react
Swiper への移行
ここからは react-swipeable-views が使われている MUI の <Tabs>
コンポーネントの Full Width の例を Swiper で置き換えていきます。
https://mui.com/material-ui/react-tabs/#full-width
この例では Swiper 単体で完結するコードとは違って、以下の2点を実装する必要があります。
<Tabs>
でスライドを制御できるようにする- 同様に、スワイプで操作したスライドと
<Tabs>
の表示を連動させる
コード例
|
|
デモ (Storybook)
https://cieloazul310.github.io/mui-swiper/?path=/story/swiper--basic
解説
react-swipeable-views では、<SwipeableViews>
コンポーネントに props を介してステート value
を直接反映できます。したがって、スライドと <Tabs>
の表示はどちらも一つのステート value
のみで制御することができました。
一方 <Swiper>
コンポーネントでは props 経由で表示スライドを制御することができません。
Swiperでは <Swiper>
コンポーネント内に存在する SwiperCore
インスタンスを使って制御する必要があります。ということは、<Tabs>
の表示と Swiper の挙動を関連づけるには、SwiperCore
インスタンスを <Swiper>
コンポーネントより上の階層で利用できるようにしなければなりません。
確認: MUI <Tabs>
の基本的な構造
|
|
準備: Swiper のインスタンス SwiperCore
をコンポーネントより上の階層で扱う
<Swiper>
コンポーネントには SwiperCore
インスタンスを受け取る際に発火する onSwiper
というイベントハンドラが用意されています。このイベントハンドラを使って SwiperCore
インスタンスを <Swiper>
コンポーネントより上の階層で利用できるように設定します。
SwiperCore
インスタンスを扱うステートフックを作成
ステートフックを作成します。型は SwiperCore | null
、初期値は null
とします。
<Swiper>
コンポーネントで生成されたインスタンスを定数 swiper
にセットする関数
<Swiper>
コンポーネントの onSwiper
イベントハンドラに設定する関数を以上のように定義します。setSwiper
に <Swiper>
コンポーネント内で生成した SwiperCore
インスタンスを通すことで、定数 swiper
が初期値の null
から SwiperCore
インスタンスに更新されます。
定義した onSwiper
をイベントハンドラに設定することで、<Swiper>
コンポーネント内部の SwiperCore
インスタンスを swiper
という定数で <Swiper>
コンポーネントの上の階層で利用できるようになりました。
次に、これを基にして以下の2点を実装していきます。
<Tabs>
でスライドを制御できるようにする- 同様に、スワイプで操作したスライドと
<Tabs>
の表示を連動させる
1. <Tabs>
でスライドを制御できるようにする
前述の通り、<Swiper>
コンポーネントの外からスライドを動かすには SwiperCore
インスタンスを使って制御する必要があります。<Tabs>
のイベントハンドラ onChange
内に onSwiper
で更新されたステート swiper
を使ったコードを加えることで、<Tabs>
でスライドを制御できるようになります。
SwiperCore
のメソッドは以下の API リファレンスで確認できます。
Methods & Properties
https://swiperjs.com/swiper-api#methods-and-properties
2. スワイプで操作したスライドと <Tabs>
の表示を連動させる
Swiper は Swiper 内部のステートの中で完結する仕様なので、スワイプ操作を行なっても <Tabs>
のステート value
は更新されません。Swiper と <Tabs>
の表示を連動させるには、<Swiper>
コンポーネントのイベントハンドラ onSlideChange
内でステート value
の値を更新するコードを記述する必要があります。
これで react-swipeable-views を使った MUI Tabs のコードを Swiper に置き換えることができました。
その他
react-swipeable-views と Swiper のデフォルト値
Swiper ではマウスによるスライド操作がデフォルトで有効になっています。react-swipeable-views ではデフォルトで無効になっているため、動作を合わせるには <Swiper>
コンポーネントの simulateTouch
props を false
に設定します。逆に react-swipeable-views でマウスによるスライド操作を有効にするには <SwipeableViews>
コンポーネントに enableMouseEvents
props を渡します。
Swiper のモジュール
Swiper では Navigation や Pagination など様々なモジュールが用意されています。React で利用するには <Swiper>
コンポーネントの modules
props にインポートしたモジュールを配列として指定することで実装できます。
Demos
https://swiperjs.com/demos
以下のコードはキーボードによるスライド操作を実装する Keyboard
モジュールを実装する例です。
|
|
Using JS Modules
https://swiperjs.com/swiper-api#using-js-modules
Storybook による動作デモ
Storybook で作成したデモページとリポジトリです
動作デモ
https://cieloazul310.github.io/mui-swiper/
リポジトリ
https://github.com/cieloazul310/mui-swiper
リンク
Bad Moon Rising / Creedence Clearwater Revival (1969)