SWR
8m 40s
SWR はクライアントからデータを取得する際に使用するライブラリです。Tanstack Query と同じカテゴリのツールになります。
いつ使うのか?
以下のシーンで使用します。
- 無限スクロールなど、データを積み上げていくような場合
- 複雑な構造における楽観的更新が必要な場合
- シンプルなグローバル状態の管理
- Cache Component が動かない環境にデプロイする場合
以前までパーソラナイズされたデータの取得を SWR で行うことで、画面を静的生成できるメリットがありました。今では Next.js の Cache Component を有効にすることで PPR(部分的な事前生成)が可能になったため、静的生成のために SWR を使う必要はなくなりました。
使い方
- SWR からアクセスするエンドポイントを作成
- SWR のカスタムフックを作成
- カスタムフックを使用してデータを取得
Server Actions をデータ取得用途で使うのは非推奨であるため、SWRからデータを取得するためにルートハンドラー(APIエンドポイント)を作成します。
基本的な仕組み
- SWR にはキーと取得関数(通常共通)を設定します。同じキーを参照する場合はキャッシュが利用されます。
- キーが変わると取得関数が再実行されます。
- 通常SWRキーごとにカスタムフックを作成し、再利用します。
- mutate によりデータを再取得し、キャッシュを更新します。
- SWR からはさまざまな状態やメソッドが返却されます
- data: データ
- error: エラー
- isLoading: ローディング中かどうか(初回)
- isValidating: データが検証中かどうか(初回以降)
- mutate: データを再取得する
ベーシックなSWRフックです。
Immutable とは
swr/immutable を使うとキャッシュが自動で更新されなくなります。無駄なデータの再取得を防ぐことができます。
基本機能は同じですが、mutate を実行しない限り一度キャッシュした情報がずっと使用されます。データ通信を節約できる反面、mutate を手動で行わないと古いデータがユーザーに表示され続けるので注意が必要です。
immutable を使わない場合、以下のタイミングでデータが自動的に再取得されます。
- フォーカスが外れたとき
- 使用するコンポーネントがマウントされた時
- ブラウザのタブを切り替えたとき
たとえば画面AでSWRフックを使用していたとします。画面Bに移動すると画面Aはアンマウントされ、再び戻ってくると画面Aが再度マウントされるため、mutate(データの再取得&キャッシュの更新)が実行されます。つまり画面を往復するたびにデータ取得が発生します。
無限スクロールにSWRを使う
エンドポイントの作成
エンドポイントでは内部的にデータアクセスレイヤー(データ取得用の関数)を使用します。これによりセキュリティリスクを低減します。
カスタムフックで共有するフェッチャーを作成
fetch の処理は基本固定なので共有化しておくと便利です。
カスタムフックの作成
画面の実装
追加読み込みの判定に react-intersection-observer を使用します。
複雑な構造における楽観的更新
シンプルな構造の場合 useOptimistic で楽観的更新が可能ですが、複雑な構造の場合は useSWR で使う方がシンプルです。
SWRフックを作成
mutate の使用時に楽観的更新を有効にする
これにより、新規タスクの作成と同時に画面が更新されますが、サーバー側の処理が失敗したら元に戻ります。多くの場合送信用のコンポーネントと一覧表示用のコンポーネントは別の場所になるため、useOptimistic を使うと Context を介して楽観的更新を伝搬させることになります。SWRはコンポーネントの階層を問わないため、楽観的更新の反映を自動で行うことができます。
シンプルな状態管理用途で使う
フェッチャーを空にすることでシンプルなグローバル状態管理用途で使用できます。