import { Callout } from 'nextra-theme-docs'
この機能を使用するには、最新のバージョン( ≥ 1.0.0 )にアップグレードしてください。 ほとんどの場合、キャッシュを直接変更しないでください。予期しない動作が発生する可能性があります。キーを手動で変更する必要がある場合は、 SWR API の使用を検討してください。参照:[ミューテーション](/docs/mutation), [テストケース間のキャッシュのリセット](#テストケース間のキャッシュのリセット)
デフォルトでは、 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
}
たとえば、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 インスタンスから読み取りと書き込みを行います。また、特定のユースケースに合わせて、他のキャッシュプロバイダーの実装を使用することもできます。
import { Cache } from '@components/diagrams/cache'
ネストされている場合、 SWR フックは上位レベルのキャッシュプロバイダーを使用します。もし上位レベルのキャッシュプロバイダーが無い場合は、空の Map
をデフォルトのキャッシュプロバイダーとして使用します。
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>
キャッシュプロバイダー API の柔軟性により、"部分的な変更"のヘルパーを構築することもできます。
以下の例では、 matchMutate
はキーとして正規表現を受け取り、パターンに一致するものを変更するために使用できます。
function useMatchMutate() {
const { cache, mutate } = useSWRConfig()
return (matcher, ...args) => {
if (!(cache instanceof Map)) {
throw new Error('matchMutate requires the cache provider to be a Map instance')
}
const keys = []
for (const key of cache.keys()) {
if (matcher.test(key)) {
keys.push(key)
}
}
const mutations = keys.map((key) => mutate(key, ...args))
return Promise.all(mutations)
}
}
次に、コンポーネントの内部:
function Button() {
const matchMutate = useMatchMutate()
return <button onClick={() => matchMutate(/^\/api\//)}>
Revalidate all keys start with "/api/"
</button>
}
キャッシュを 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>
アプリケーションをテストするときは、テストケース間で SWR キャッシュをリセットすることをオススメします。空のキャシュプロバイダーでアプリケーションをラップするだけです。 Jest の例を次に示します:
describe('test suite', async () => {
it('test case', async () => {
render(
<SWRConfig value={{ provider: () => new Map() }}>
<App/>
</SWRConfig>
)
})
})
警告:キャッシュに直接書き込むことはするべきではありません。予期しない動作が発生する可能性があります。
const { cache } = useSWRConfig()
cache.get(key) // キーの現在のデータを取得します。
cache.clear() // ⚠️ すべてのキャッシュをクリアします。 SWRは、再レンダリング時に再検証します。