こんにちは。キカガクプラットフォーム部の石橋です。
キカガク for Business ではクライアントフェッチのライブラリとして SWR を採用しています。 SWR の使いこなし術として、SWR 2.0 から追加されたオプションのひとつである keepPreviousData を使いローディング処理の最適化を行っていますので keepPreviousData の解説と実際の取組みを紹介していきます。
keepPreviousData で何が変わるのか?
const { data, isLoading } = useSWR('key', () => {}, { keepPreviousData: true });
ずばり、key が変わったタイミングでも次のデータフェッチが完了するまでは以前の key のデータを保持し続けることができます。
とはいっても、それで何が良いのかイメージがわかりにくいため実際の利用ケースを想定して解説していきます。
セレクトボックスを切り替えるたびに画面に表示されるデータが切り替わるような UI を想像してみましょう。
例えば、下記のスクリーンショットは実際のキカガク for Business のアプリ画面です。
この画面では企業に所属する受講者のテスト受検結果を表示しています。赤矢印のセレクトボックスで様々な条件を指定し受検結果を表示することができるようになっています。
keepPreviousData が false の場合の挙動
まずは何も考えずに上記のようなケースを想定して SWR で実装をしてみます。
// テストの種類を変えるたびに、そのテストのデータを取得する const { data, isLoading } = useSWR(examType, () => {});
key として渡している examType はテストの種別を持った変数です。セレクトボックスでテストの種類を切り替えるたびに key が変わるためその都度データフェッチが行われるイメージです。
ここで useSWR の返り値である data の中身に注目して挙動を考えてみましょう。
下記の画像の通り key が変わったタイミング (Key Change) で data は undefined になります。
つまり、セレクトボックスを切り替えた後に次のデータフェッチが完了するまでは画面に表示される値が一時的になくなってしまいます。
ローディングアニメーションをどう実装するか次第ではありますが、これではセレクトボックスを切り替えるたびにローディングアニメーションを入れる必要があり、良いユーザー体験とは言い切れません。
keepPreviousData が true の場合の挙動
では次に keepPreviousData を有効にしてみます。
// テストの種類を変えるたびに、そのテストのデータを取得する const { data, isLoading } = useSWR(groupId, () => {}, {keepPreviousData: true});
このときの data の中身は添付の通り、key が変わったタイミング (Key Change) でも data が undefined にはならず、key が変わる前の value(1) を持ち続けます。
そして key が変わったあとのデータフェッチが完了すると value(2) に置き換わります。
つまりセレクトボックスを切り替えるたびに画面に表示される値がなくなったり、無駄なローディングアニメーションで画面がチカチカすることが keepPreviousData を有効にするだけで防ぐことができ自然なユーザー体験を提供することができるようになります。
注意点
keepPreviousData はあくまで key が変わっても次のデータフェッチが完了するまで以前の key の値を持ち続ける機能となります。
そのため一度のリクエストで取得するデータ量が膨大でデータフェッチに時間がかかる場合などは、セレクトボックスの切り替えタイミングと新しいデータが画面に描画されるまでにラグが生まれてしまい逆にユーザーにストレスを与えてしまうことになります。
そのようなケースでは、素直に isLoading を使い UI の制御を行うと良いと思います。
まとめ
SWR には非常に多くのオプションが用意されており、今回のように通常の hooks に一手間加えてあげるだけでユーザー体験アップにつながるようなものもあります。
すべてを使いこなすのはなかなか難しいですが、少しでも自由に扱えるオプションが増えるようにドキュメントをもっと読み込みたいと思います。
また、キカガクでは一緒に働く仲間を募集中です。 モダンな技術を用いながら教育事業に携わりたいという方はぜひ採用情報をご覧ください。ここまでお読みいただきありがとうございました!