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