主旨
Reactのスイープ処理ライブラリ、Swiperを使用してみたけど、意外ともっさりしてた。
pure jsでスイープ処理を実現するサイトを参考にして、スイープ処理を自作した話。
Swiper
こちら。
Reactでスイープ処理を実現しようとすると、一番の候補となる。
なんか、思ってたよりももっさりしてるな
実現したい要件としては、ネイティブアプリのTrelloのリスト切り替え時くらいのレスポンス。
だけど、スマホでSwiperのdemo操作をして、もっさりすることが判明。また、実際にアプリに組み込んでみても、案の定、もっさり動作することが判明。
普通にストレスフル。
pure js ならばどうか
参考サイト
デモサイト(スマホのみ反応)
めっちゃいい。私の望むレスポンスに近い。しかもどれくらい動かした時にスイープしたと判断する閾値も変えられる。
React上で実装できるか?
タッチイベントをReactでどう実現するかを調べた。ググればいっぱい出てきた。
参考サイト
実装
カスタムフックとして切り出した。
import { TouchEvent, useState } from "react"
export const useSwipe = () => {
const dist = 80;
const [startX, setStartX] = useState(0);
const [moveX, setMoveX] = useState(0);
const [currentIndex, setCurrentIndex] = useState(0);
const touchStartHandler = (e: TouchEvent<HTMLDivElement>) => {
setStartX(e.touches[0].pageX);
}
const touchMoveHandler = (e: TouchEvent<HTMLDivElement>) => {
setMoveX(e.changedTouches[0].pageX);
}
return {
currentIndex, startX, moveX, dist,
touchStartHandler, touchMoveHandler, setCurrentIndex,
}
}
呼び出し側
export const MyComponent: FC = () => {
const { currentIndex, startX, moveX, dist,
touchStartHandler, touchMoveHandler, setCurrentIndex } = useSwipe();
return(
<>
<div
onTouchStart={touchStartHandler}
onTouchMove={touchMoveHandler}
onTouchEnd={() => {
if (startX > moveX && startX > moveX + dist) {
// 右へスイープした場合の処理
}
else if (startX < moveX && startX + dist < moveX) {
// 左へスイープした場合の処理
}
}}
>
</div>
</>
)};
スイープ完了時の処理も、コンポーネントのstateに依存しなければ、フック側に記述可能
実演
スイープ処理を行いたいアプリで、動作確認した。
いいじゃん。ノーストレスフル。
結果
Swiperよりも、最小限で、高レスポンスなスイープ処理を実現できた。
pure jsの処理をReact上に実装する手法も学べた。