動かして学ぶ データ取得のための React Hooks ライブラリ SWR の自動再検証機能

# はじめに
この記事では、データ取得のための React Hooks ライブラリである SWR の自動再検証（再取得）機能について、実際に動かしながら確認していきます。

https://swr.vercel.app/

# 前提
サンプルコードの開発環境は以下の通りです。

- Windows11
- VSCode
- Next.js 13.4.19
- React 18.2.0
- SWR 2.2.2
- TypeScript 5.2.2

今回利用したサンプルコードは、以下のリポジトリに載せてあります。

https://github.com/yasushi-mo/swr-sample

# 再検証機能の設定方法
各再検証機能の確認をする前に設定方法について、記載します。
以下2つの方法があります。

## グローバルで設定する
```SWRConfig``` コンテキストの ```value``` に設定値を渡すことで、コンテキストで囲まれたコンポーネントの設定を一括で行うことができます。

```index.tsx
<SWRConfig
  value={{
    revalidateOnFocus: false,
    revalidateOnReconnect: false,
    revalidateIfStale: false,
  }}
>
  <Component />
</SWRConfig>
```

## hooks ごとに設定する
hooks ごとに設定する場合、```useSWR``` の第3引数に設定値を渡します。

```index.ts
const { data } = useSWR("https://hoge.com/api", fetcher, {
    revalidateOnFocus: false,
    revalidateOnReconnect: false,
    revalidateIfStale: false,
  })
```

それでは、各再検証機能の確認をしていきます。

# マウント時の再検証
コンポーネントのマウント時の再検証には、```revalidateOnMount``` と ```revalidateIfStale``` を利用します。

```revalidateOnMount``` を true にすると、マウント時に必ず再検証が行われます。
![localhost_3000_auto-revalidation-Google-Chrome-2023-09-03-20-12-51.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318188/586ce73f-8848-587d-8b41-f6fbd5cdf727.gif)


```revalidateOnMount``` は利用せず（ture にも false にもせず）、```revalidateIfStale``` を ***false*** にすると、以下のようにキャッシュの有無で再検証の実行有無が決まります。
- キャッシュなし：再検証が行われる
- キャッシュあり；再検証が行われない

![localhost_3000_auto-revalidation-Google-Chrome-2023-09-03-20-13-51.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318188/1885604d-f869-1bcc-d4b5-1c9f4763c32e.gif)


また、true の場合、キャッシュの有無に関わらず、マウント時に必ず再検証が行われます。

:::note
```revalidateOnMount``` のデフォルト値は undefined、```revalidateIfStale``` のデフォルト値は true です。
そのため、デフォルトの状態では、マウント時に必ず再検証が行われます。

```revalidateOnMount``` と ```revalidateIfStale``` の設定値、キャッシュの有無による再検証の実行有無を整理すると以下のようになります。

| ```revalidateOnMount``` | ```revalidateIfStale``` | キャッシュ | 再検証 |
| -------- | -------- | -------- | -------- |
| true | どちらでも | どちらでも | 有 |
| false | どちらでも | どちらでも | 無 |
| undefined（デフォルト値）  |  true（デフォルト値）  | どちらでも  |  有  |
| undefined | false | 無 | 有 |
| undefined | false | 有 | 無 |
:::

# フォーカス時の再検証
```revalidateOnFocus``` を true にすると、ブラウザのタブが再度フォーカスされた時に再検証が行われます。
![localhost_3000_auto-revalidation-Google-Chrome-2023-09-03-20-17-53.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318188/9f989370-da41-c37a-d1dd-b3fc8f571094.gif)

:::note
```revalidateOnFocus``` のデフォルト値は true です。
:::

# 定期的な再検証
```refreshInterval``` に数値を与えると、その数値のミリ秒ごとに再検証が行われます。
![localhost_3000_auto-revalidation-Google-Chrome-2023-09-03-20-18-20.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318188/60f830b3-716f-c72e-8545-19abf251cd90.gif)


# 再接続時の再検証
```revalidateOnReconnect``` を true にすると、ネットワーク再接続時に再検証が行われます。
![localhost_3000_auto-revalidation-Google-Chrome-2023-09-03-20-18-43.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318188/ce18c296-1b29-7832-ac2f-2a026630b37f.gif)

:::note
```revalidateOnReconnect``` のデフォルト値は true です。
:::

# 自動再検証の無効化
```useSWRImmutable``` という hook を使うと今まで紹介した再検証を無効にできます。
![localhost_3000_auto-revalidation-Google-Chrome-2023-09-03-20-19-40.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318188/12f10714-7498-aabd-a91d-ad79832fc5a5.gif)

:::note
```useSWRImmutable``` の設定内容は、```useSWR``` を使った際の以下の設定内容と同じです。そのため、初回マウント時以外は再検証が行われません。

```index.tsx
useSWR(key, fetcher, {
  revalidateIfStale: false,
  revalidateOnFocus: false,
  revalidateOnReconnect: false
});
```
:::

# まとめ
この記事では、SWR の自動再検証機能を実際に動かしながら確認していきました。色々設定できて便利なので、ユースケースに適した使い方をしていきたいです。

# 参考
- [API](https://swr.vercel.app/docs/api)
- [Automatic Revalidation](https://swr.vercel.app/docs/revalidation)
- [Global Configuration](https://swr.vercel.app/docs/global-configuration)