キャッシュ
この機能を使用するには、最新バージョン(≥ 1.0.0)にアップグレードしてください。
ほとんどの場合、キャッシュに直接書き込むべきではありません。SWRの動作が予期せぬものになる可能性があります。キーを手動で変更する必要がある場合は、SWR APIを使用することを検討してください。
こちらも参照してください:ミューテーション、テストケース間のキャッシュのリセット。
デフォルトでは、SWRはグローバルキャッシュを使用して、すべてのコンポーネント間でデータを保存および共有します。ただし、SWRConfig
のprovider
オプションを使用して、この動作をカスタマイズすることもできます。
キャッシュプロバイダーは、よりカスタマイズされたストレージでSWRを有効にすることを目的としています。
キャッシュプロバイダー
キャッシュプロバイダーは、次のTypeScript定義に一致するMapのようなオブジェクトです(swr
からインポートできます)。
interface Cache<Data> {
get(key: string): Data | undefined
set(key: string, value: Data): void
delete(key: string): void
keys(): IterableIterator<string>
}
たとえば、JavaScriptのMap(新しいタブで開きます)インスタンスは、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コンポーネント内では、useSWRConfig
フックを使用して、mutate
を含む現在のキャッシュプロバイダーと他の設定にアクセスする必要があります。
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() {
// When initializing, we restore the data from `localStorage` into a map.
const map = new Map(JSON.parse(localStorage.getItem('app-cache') || '[]'))
// Before unloading the app, we write back all the data into `localStorage`.
window.addEventListener('beforeunload', () => {
const appCache = JSON.stringify(Array.from(map.entries()))
localStorage.setItem('app-cache', appCache)
})
// We still use the map for write & read for performance.
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>
)
})
})
キャッシュデータの変更
キャッシュに直接書き込むべきではありません。未定義の動作を引き起こす可能性があります。
mutate
を使用してキャッシュを変更できます。例えば、以下の様にすべてのキャッシュデータをクリアできます。
const { mutate } = useSWRConfig()
mutate(
key => true, // which cache keys are updated
undefined, // update cache data to `undefined`
{ revalidate: false } // do not revalidate
)
詳細はこちらをご覧ください。