はじめに
この記事では、データ取得のための React Hooks ライブラリである SWR の自動再検証(再取得)機能について、実際に動かしながら確認していきます。
前提
サンプルコードの開発環境は以下の通りです。
- Windows11
- VSCode
- Next.js 13.4.19
- React 18.2.0
- SWR 2.2.2
- TypeScript 5.2.2
今回利用したサンプルコードは、以下のリポジトリに載せてあります。
再検証機能の設定方法
各再検証機能の確認をする前に設定方法について、記載します。
以下2つの方法があります。
グローバルで設定する
SWRConfig コンテキストの value に設定値を渡すことで、コンテキストで囲まれたコンポーネントの設定を一括で行うことができます。
<SWRConfig
value={{
revalidateOnFocus: false,
revalidateOnReconnect: false,
revalidateIfStale: false,
}}
>
<Component />
</SWRConfig>
hooks ごとに設定する
hooks ごとに設定する場合、useSWR の第3引数に設定値を渡します。
const { data } = useSWR("https://hoge.com/api", fetcher, {
revalidateOnFocus: false,
revalidateOnReconnect: false,
revalidateIfStale: false,
})
それでは、各再検証機能の確認をしていきます。
マウント時の再検証
コンポーネントのマウント時の再検証には、revalidateOnMount と revalidateIfStale を利用します。
revalidateOnMount を true にすると、マウント時に必ず再検証が行われます。

revalidateOnMount は利用せず(ture にも false にもせず)、revalidateIfStale を false にすると、以下のようにキャッシュの有無で再検証の実行有無が決まります。
- キャッシュなし:再検証が行われる
- キャッシュあり;再検証が行われない
また、true の場合、キャッシュの有無に関わらず、マウント時に必ず再検証が行われます。
revalidateOnMount のデフォルト値は undefined、revalidateIfStale のデフォルト値は true です。
そのため、デフォルトの状態では、マウント時に必ず再検証が行われます。
revalidateOnMount と revalidateIfStale の設定値、キャッシュの有無による再検証の実行有無を整理すると以下のようになります。
revalidateOnMount |
revalidateIfStale |
キャッシュ | 再検証 |
|---|---|---|---|
| true | どちらでも | どちらでも | 有 |
| false | どちらでも | どちらでも | 無 |
| undefined(デフォルト値) | true(デフォルト値) | どちらでも | 有 |
| undefined | false | 無 | 有 |
| undefined | false | 有 | 無 |
フォーカス時の再検証
revalidateOnFocus を true にすると、ブラウザのタブが再度フォーカスされた時に再検証が行われます。

revalidateOnFocus のデフォルト値は true です。
定期的な再検証
refreshInterval に数値を与えると、その数値のミリ秒ごとに再検証が行われます。

再接続時の再検証
revalidateOnReconnect を true にすると、ネットワーク再接続時に再検証が行われます。

revalidateOnReconnect のデフォルト値は true です。
自動再検証の無効化
useSWRImmutable という hook を使うと今まで紹介した再検証を無効にできます。

useSWRImmutable の設定内容は、useSWR を使った際の以下の設定内容と同じです。そのため、初回マウント時以外は再検証が行われません。
useSWR(key, fetcher, {
revalidateIfStale: false,
revalidateOnFocus: false,
revalidateOnReconnect: false
});
まとめ
この記事では、SWR の自動再検証機能を実際に動かしながら確認していきました。色々設定できて便利なので、ユースケースに適した使い方をしていきたいです。
