Skip to content
开发文档
高级
缓存

缓存

¥Cache

💡

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

¥Upgrade to the latest version (≥ 1.0.0) to use this feature.

⚠️

在大多数情况下,你不应该直接写入缓存,这可能会导致 SWR 出现未定义的行为。如果你需要手动更改键,请考虑使用 SWR API。
另请参阅:修改在测试用例之间重置缓存

¥In most cases, you shouldn't directly write to the cache, which might cause undefined behaviors of SWR. If you need to manually mutate a key, please consider using the SWR APIs.
See also: Mutation, Reset Cache Between Test Cases.

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

¥By default, SWR uses a global cache to store and share data across all components. But you can also customize this behavior with the provider option of SWRConfig.

缓存提供程序旨在为 SWR 提供更多定制的存储。

¥Cache providers are intended to enable SWR with more customized storages.

缓存提供者

¥Cache Provider

缓存提供程序是类似 Map 的对象,它与以下 TypeScript 定义匹配(可以从 swr 导入):

¥A cache provider is Map-like object which matches the following TypeScript definition (which can be imported from swr):

interface Cache<Data> {
  get(key: string): Data | undefined
  set(key: string, value: Data): void
  delete(key: string): void
  keys(): IterableIterator<string>
}

例如,JavaScript 映射 (opens in a new tab) 实例可以直接用作 SWR 的缓存提供者。

¥For example, a JavaScript Map (opens in a new tab) instance can be directly used as the cache provider for SWR.

创建缓存提供者

¥Create Cache Provider

SWRConfigprovider 选项接收一个返回 缓存提供者 的函数。然后该提供程序将被 SWRConfig 边界内的所有 SWR 钩子使用。例如:

¥The provider option of SWRConfig receives a function that returns a cache provider. The provider will then be used by all SWR hooks inside that SWRConfig boundary. For example:

import useSWR, { SWRConfig } from 'swr'
 
function App() {
  return (
    <SWRConfig value={{ provider: () => new Map() }}>
      <Page/>
    </SWRConfig>
  )
}

<Page/> 内的所有 SWR 钩子都将从该 Map 实例读取和写入。你还可以针对你的特定用例使用其他缓存提供程序实现。

¥All SWR hooks inside <Page/> will read and write from that Map instance. You can also use other cache provider implementations as well for your specific use case.

💡

在上面的例子中,当重新挂载 <App/> 组件时,Provider 也会被重新创建。缓存提供程序应该放在组件树中更高的位置,或者放在渲染之外。

¥In the example above, when the <App/> component is re-mounted, the provider will also be re-created. Cache providers should be put higher in the component tree, or outside of render.

嵌套时,SWR 钩子将使用上层缓存提供程序。如果没有上层缓存提供程序,则会回退到默认缓存提供程序,即空的 Map

¥When nested, SWR hooks will use the upper-level cache provider. If there is no upper-level cache provider, it fallbacks to the default cache provider, which is an empty Map.

⚠️

如果使用缓存提供程序,则全局 mutate 将不适用于该 <SWRConfig> 边界下的 SWR 钩子。请使用 this 代替。

¥If a cache provider is used, the global mutate will not work for SWR hooks under that <SWRConfig> boundary. Please use this instead.

访问当前缓存提供者

¥Access Current Cache Provider

在 React 组件内部时,你需要使用 useSWRConfig 钩子来访问当前缓存提供程序以及包括 mutate 在内的其他配置:

¥When inside a React component, you need to use the useSWRConfig hook to get access to the current cache provider as well as other configurations including mutate:

import { useSWRConfig } from 'swr'
 
function Avatar() {
  const { cache, mutate, ...extraConfig } = useSWRConfig()
  // ...
}

如果不在任何 <SWRConfig> 下,它将返回默认配置。

¥If it's not under any <SWRConfig>, it will return the default configurations.

实验:扩展缓存提供者

¥Experimental: Extend Cache Provider

🧪

这是一项实验性功能,该行为可能会在未来的升级中发生变化。

¥This is an experimental feature, the behavior might change in future upgrades.

当嵌套多个 <SWRConfig> 组件时,可以扩展缓存提供程序。

¥When multiple <SWRConfig> components are nested, cache provider can be extended.

provider 函数的第一个参数是上层 <SWRConfig> 的缓存提供程序(如果没有父级 <SWRConfig>,则为默认缓存),你可以使用它来扩展缓存提供程序:

¥The first argument for the provider function is the cache provider of the upper-level <SWRConfig> (or the default cache if there's no parent <SWRConfig>), you can use it to extend the cache provider:

<SWRConfig value={{ provider: (cache) => newCache }}>
  ...
</SWRConfig>

示例

¥Examples

基于 LocalStorage 的持久缓存

¥LocalStorage Based Persistent Cache

你可能希望将缓存同步到 localStorage。这是一个示例实现:

¥You might want to sync your cache to localStorage. Here's an example implementation:

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
}

然后将其用作提供者:

¥Then use it as a provider:

<SWRConfig value={{ provider: localStorageProvider }}>
  <App/>
</SWRConfig>
💡

作为改进,你还可以将内存缓存用作缓冲区,并定期写入 localStorage。你还可以使用 IndexedDB 或 WebSQL 实现类似的分层缓存。

¥As an improvement, you can also use the memory cache as a buffer, and write to localStorage periodically. You can also implement a similar layered cache with IndexedDB or WebSQL.

在测试用例之间重置缓存

¥Reset Cache Between Test Cases

测试应用时,你可能希望在测试用例之间重置 SWR 缓存。你可以简单地使用空的缓存提供程序封装你的应用。这是一个 Jest 的例子:

¥When testing your application, you might want to reset the SWR cache between test cases. You can simply wrap your application with an empty cache provider. Here's an example with Jest:

describe('test suite', async () => {
  it('test case', async () => {
    render(
      <SWRConfig value={{ provider: () => new Map() }}>
        <App/>
      </SWRConfig>
    )
  })
})

修改缓存数据

¥Modify the Cache Data

🚨

你不应该直接写入缓存,这可能会导致未定义的行为。

¥You should not write to the cache directly, it might cause undefined behavior.

你可以使用 mutate 来修改缓存。例如,你可以像下面这样清除所有缓存数据。

¥You can use mutate to modify the cache. For example, you can clear all cache data like the following.

const { mutate } = useSWRConfig()
 
mutate(
  key => true, // which cache keys are updated
  undefined, // update cache data to `undefined`
  { revalidate: false } // do not revalidate
)

更多信息可参见 此处

¥More information can be found here.