缓存示例
在阅读本指南前,请务必仔细阅读 重要默认值
基础示例
该缓存示例说明了以下内容的生命周期与行为:
- 具有或不具有缓存数据的查询实例
- 后台拉取
- 非活跃查询
- 垃圾回收
我们假设使用默认 gcTime(5 分钟)和默认 staleTime(0)。
- 一个
injectQuery(() => ({ queryKey: ['todos'], queryFn: fetchTodos }))新实例被初始化。- 由于此前未使用
['todos']查询键发起过任何查询,该查询将立即显示硬加载状态,并发起网络请求以拉取数据。 - 网络请求完成后,返回的数据将被缓存在
['todos']键下。 - 数据将在配置的
staleTime(默认为0,或立即)后被标记为过期。
- 由于此前未使用
- 另一处初始化了第二个
injectQuery(() => ({ queryKey: ['todos'], queryFn: fetchTodos }))实例。- 由于缓存中已存在第一个查询所写入的
['todos']键对应的数据,该数据会立即从缓存中返回。 - 新实例会使用其查询函数触发一次新的网络请求。
- 注意:无论两个
fetchTodos查询函数是否完全相同,只要它们拥有相同的查询键,两者的status(包括isFetching、isPending及其他相关值)都会被更新。
- 注意:无论两个
- 当请求成功完成时,缓存中
['todos']键下的数据将被新数据覆盖,且两个实例均会收到更新后的数据。
- 由于缓存中已存在第一个查询所写入的
injectQuery(() => ({ queryKey: ['todos'], queryFn: fetchTodos }))查询的两个实例均被销毁,不再使用。- 由于该查询已无任何活跃实例,系统将基于
gcTime启动垃圾回收超时机制,以删除并回收该查询(默认为 5 分钟)。
- 由于该查询已无任何活跃实例,系统将基于
- 在缓存超时完成前,另一个
injectQuery(() => ({ queryKey: ['todos'], queryFn: fetchTodos }))实例被挂载。该查询会立即返回当前可用的缓存数据,同时在后台执行fetchTodos函数。当其成功完成时,将用新鲜数据填充缓存。 injectQuery(() => ({ queryKey: ['todos'], queryFn: fetchTodos }))的最后一个实例被销毁。- 此后 5 分钟 内未再出现任何
injectQuery(() => ({ queryKey: ['todos'], queryFn: fetchTodos }))实例。['todos']键下的缓存数据将被删除并完成垃圾回收。
如需了解更高级的用法,请参阅 injectQuery。