快取
升級至最新版本(≥ 1.0.0)以使用此功能。
在大多數情況下,您不應直接「寫入」快取,這可能會導致 SWR 未定義的行為。如果您需要手動變更一個鍵,請考慮使用 SWR API。
另請參閱:變更、在測試案例之間重設快取。
預設情況下,SWR 使用全域快取來儲存並在所有元件之間共享資料。但您也可以使用 SWRConfig
的 provider
選項來自訂此行為。
快取供應器旨在讓 SWR 能夠使用更多自訂的儲存方式。
快取供應器
快取供應器是一個類似 Map 的物件,其符合以下的 TypeScript 定義(可以從 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
)
更多資訊可以在這裡找到。