跳到内容
文档
高级
缓存

缓存

💡

升级到最新版本(≥ 1.0.0)以使用此功能。

⚠️

在大多数情况下,您不应该直接写入缓存,这可能会导致 SWR 的行为不确定。如果您需要手动更改密钥,请考虑使用 SWR API。
另请参阅: 变异在测试用例之间重置缓存.

默认情况下,SWR 使用全局缓存来存储和共享所有组件的数据。但是您也可以使用 provider 选项 SWRConfig 自定义此行为。

缓存提供者旨在使 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 的缓存提供者。

创建缓存提供者

provider 选项 SWRConfig 接收一个函数,该函数返回一个 缓存提供者。然后,该提供者将被该 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
)

有关更多信息,请访问 这里