Cache
この機能を使用するには、最新のバージョン( ≥ 1.0.0 )にアップグレードしてください。
ほとんどの場合、キャッシュを直接変更しないでください。予期しない動作が発生する可能性があります。キーを手動で変更する必要がある場合は、 SWR API の使用を検討してください。
参照:ミューテーション, テストケース間のキャッシュのリセット
デフォルトでは、 SWR はグローバルキャッシュを使用して、すべてのコンポーネント間でデータを保存および共有します。ただし、 SWRConfig
の provider
オプションを使用して、その挙動をカスタマイズできます。
キャッシュプロバイダーは、よりカスタマイズされたストレージで SWR を実現することを目的としています。
キャッシュプロバイダー
キャッシュプロバイダーは、次の TypeScript 定義( swr
からインポート可能 )に一致する Map のようなオブジェクトです:
interface Cache<Data> {
get(key: string): Data | undefined
set(key: string, value: Data): void
delete(key: string): void
keys(): IterableIterator<string>
}
たとえば、JavaScript Map (opens in a new tab) インスタンスを SWR のキャッシュプロバイダーとして直接使用できます。
キャッシュプロバイダーの作成
SWRConfig
の provider
オプションは、 キャッシュプロバイダーを返す関数を受け取ります。受け取ったプロバイダーは、その SWRConfig
の範囲内のすべての SWR フックで使用されます。例:
import useSWR, { SWRConfig } from 'swr'
function App() {
return (
<SWRConfig value={{ provider: () => new Map() }}>
<Page/>
</SWRConfig>
)
}
<Page />
内のすべての SWR フックは、その Map インスタンスから読み取りと書き込みを行います。また、特定のユースケースに合わせて、他のキャッシュプロバイダーの実装を使用することもできます。
上記の例では、 <App />
コンポーネントが再マウントされると、プロバイダーも再生成します。キャッシュプロバイダーは、コンポーネントツリーの上位、またはレンダリングの外部に配置する必要があります。
ネストされている場合、 SWR フックは上位レベルのキャッシュプロバイダーを使用します。もし上位レベルのキャッシュプロバイダーが無い場合は、空の Map
をデフォルトのキャッシュプロバイダーとして使用します。
キャッシュプロバイダーを使用している場合、グローバルな mutate
は <SWRConfig />
以下の SWR フックでは機能しません。代わりに こちら を使用してください。
現在のキャッシュプロバイダーにアクセスする
React コンポーネント内では、 mutate
を含む他の設定と同様に、現在のキャッシュプロバイダーへアクセスするために、 useSWRConfig フックを使用する必要があります。
import { useSWRConfig } from 'swr'
function Avatar() {
const { cache, mutate, ...extraConfig } = useSWRConfig()
// ...
}
<SWRConfig>
以下でない場合は、デフォルトの設定を返します。
実験的:キャッシュプロバイダーの拡張
これは実験的な機能であり、将来のアップグレードで動作が変更される可能性があります。
複数の <SWRConfig>
コンポーネントがネストされている場合、キャッシュプロバイダーを拡張できます。
provider
の最初の引数は、上位レベルの <SWRConfig>
のキャッシュプロバイダー( 親が <SWRConfig>
でない場合はデフォルトのキャッシュ )です。これを使用して、キャッシュプロバイダーを拡張できます:
<SWRConfig value={{ provider: (cache) => newCache }}>
...
</SWRConfig>
例
LocalStorage を使った永続キャッシュ
キャッシュを localStorage
で同期しても良いかもしれません。実装例は次の通りです:
function localStorageProvider() {
// 初期化時に、 `localStorage` から Map にデータを復元します。
const map = new Map(JSON.parse(localStorage.getItem('app-cache') || '[]'))
// アプリが終了する前に、すべてのデータを `localStorage` に保存します。
window.addEventListener('beforeunload', () => {
const appCache = JSON.stringify(Array.from(map.entries()))
localStorage.setItem('app-cache', appCache)
})
// パフォーマンスのために、書き込みと読み取りには引き続き Map を使用します。
return map
}
次に、プロバイダーとして使用します:
<SWRConfig value={{ provider: localStorageProvider }}>
<App/>
</SWRConfig>
改善点として、メモリキャッシュをバッファとして使用し、定期的に localStorage
に書き込むこともできます。 IndexedDB または WebSQL を使用して同様の階層化キャッシュを実装することもできます。
テストケース間のキャッシュのリセット
アプリケーションをテストするときは、テストケース間で SWR キャッシュをリセットすることをオススメします。空のキャッシュプロバイダーでアプリケーションをラップするだけです。 Jest の例を次に示します:
describe('test suite', async () => {
it('test case', async () => {
render(
<SWRConfig value={{ provider: () => new Map() }}>
<App/>
</SWRConfig>
)
})
})
キャッシュを更新する
const { cache } = useSWRConfig()
cache.get(key) // キーの現在のデータを取得します。
キャッシュに直接書き込むことはするべきではありません。予期しない動作が発生する可能性があります。
mutate
をキャッシュを更新するために利用できます。例えば、下記のようにすることで全てのキャッシュデータをクリアできます。
const { mutate } = useSWRConfig()
mutate(
key => true, // どのキャッシュキーを更新するか
undefined, // キャッシュデータを `undefined` に更新する
{ revalidate: false } // 再検証しない
)
更なる情報は こちら から確認できます。