サマリ
useSWR
の返り値としてのisLoading
が使えるのは SWR 2.0 から
isLoading は useSWR から返される新しい状態で、リクエストが実行中で、ロードされたデータがない ことを示します。これまでは、isValidating は初期ローディングと再検証の状態のどちらも表していたため、初期ローディングかどうかを知るためには data と error が undefined であるかどうかをチェックする必要がありました。
// SWRのバージョン2.0以降であれば、isLoadingを取り出せる // バージョン1.Xの場合、useSWRの返り値はisLoadingプロパティを持たないため、 // 下の変数isLoadingには「ただのundefined」が入ってしまい、状態の管理には使えない const { data, isLoading } = useSWR('/api/user', fetcher)
表題の通りですが、本記事はこのことの備忘録です。
なんでわざわざこんなことを記事に?
本記事の執筆時点で、フィヨルドブートキャンプ(以下FBC)のプラクティス「チーム開発」において、下のIssueに取り組んでいます。
アプリ右上の通知ベル(日報でのメンションなどの各種通知を確認するためのボタン)に、新機能を追加するというIssueです。
既存のベルはVueで実装されており、Reactにリプレイスすることも兼ねているIssueで、これにあたりAPIのコールとフェッチ状態・キャッシュデータの管理にuseSWR
を使おう!という流れ。
FBCではReactのカリキュラムの中に「SWRを使ってAPIをコールする」というプラクティスがあります。
ここで生徒はuseSWR
のドキュメントを読み、練習課題を解くことで基本的な使い方を学びます。
練習課題はSWRを自分でnpm install
したので、最新版のv2.X系を自然と使うことになり、ドキュメントも上記の最新のものを参照していました。
なのでこのIssueでもプラクティスで学んだ通り、初期ローディング中の状態管理にフックの返り値isLoading
を使ってみようとすると、なにやらうまくいかない。
console.log(isLoading)
でプリントデバッグを試すと、ロード中の状態と思われるタイミングでもisLoading
の中身はundefined
だったため、これは何かがおかしいと思い調査したところ、アプリで使われているSWR
のバージョンが1.3
だった、というのが根本原因でした。
// package.json // ... "sweetalert2": "^11.1.5", "swr": "^1.3.0", "tailwindcss": "^3.1.8", // ...
https://github.com/fjordllc/bootcamp/blob/main/package.json#L50
よくよく調べてみると、記事冒頭で引用したようにisLoading
は2.0
でリリースされた返り値ということ。
QiitaなどでSWRの記事を見ているときに、「なんでこの記事ではisLoading
を使用せずに!data
でローディング状態を管理しているのだろう」と思ったことがあるんですが、執筆タイミングでのバージョンの違いだった可能性があるということですね。
学び
- プロジェクトで使われているライブラリのバージョンをしっかりと確認する
- 特にネットの記事を読んでインプットする際は、バージョンの差異による挙動のズレが起こる可能性があることを強く意識する
あたりまえのことですね……。改めて、気をつけたいと思います。