缓存
¥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 使用全局缓存来存储和跨所有组件共享数据。但你也可以使用 SWRConfig
的 provider
选项自定义此行为。
¥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
SWRConfig
的 provider
选项接收一个返回 缓存提供者 的函数。然后该提供程序将被 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
.
访问当前缓存提供者
¥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.