重要默认值
开箱即用时,TanStack Query 采用激进但合理的默认配置。有时这些默认值会让新用户措手不及,或在用户不了解它们的情况下,使学习与调试变得困难。 请在持续学习和使用 TanStack Query 的过程中牢记以下要点:
- 通过
useQuery或useInfiniteQuery创建的查询实例默认将缓存数据视为过期。
若要更改此行为,你可以通过
staleTime选项在全局或每个查询级别进行配置。指定更长的staleTime意味着查询不会过于频繁地重新拉取其数据。
- 设置了
staleTime的查询在该staleTime时长未过期前被视为新鲜。
'static'和Infinity均可阻止基于过期的重新拉取,但'static'更严格:queryClient.invalidateQueries()可使设置了staleTime: Infinity的查询失效,但对staleTime: 'static'无效。refetchOnMount、refetchOnWindowFocus和refetchOnReconnect设为"always"的行为也会被'static'阻止。对于应用运行期间绝不会变更的数据(如启动时获取的功能开关、登录时加载的用户权限、静态参考表),请使用'static';若仍需支持手动使失效,则使用Infinity。
- 过期查询会在后台自动重新拉取,触发时机包括:
- 查询的新实例挂载
- 浏览器窗口重新获得焦点
- 网络重新连接
推荐通过设置
staleTime来避免过度重新拉取,但你也可以通过配置refetchOnMount、refetchOnWindowFocus和refetchOnReconnect等选项来自定义重新拉取的时机。
查询可选择性地配置
refetchInterval,以独立于staleTime设置的方式,按固定周期触发重新拉取。详情请参阅 轮询(Polling)。当查询结果不再有活跃的
useQuery、useInfiniteQuery实例或查询观察者时,该查询被标记为“非活跃”,并保留在缓存中,以备后续再次使用。默认情况下,“非活跃”查询将在 5 分钟后被垃圾回收。
若要更改此行为,你可以将查询的默认
gcTime修改为除5 * 60 * 1000毫秒以外的其他值。失败的查询会静默重试 3 次,并采用指数退避延迟,之后才捕获错误并在 UI 中显示。
若要更改此行为,你可以将查询的默认
retry和retryDelay选项修改为除3和默认指数退避函数以外的其他值。
- 查询结果默认采用结构共享(structural sharing),以检测数据是否实际发生变更;若未变更,则数据引用保持不变,从而更好地配合 useMemo 和 useCallback 实现值稳定化。如果你对此概念不熟悉,无需担心!99.9% 的情况下你无需禁用此功能,它能在零成本前提下提升应用性能。
结构共享仅适用于 JSON 兼容的值;其他任何类型值均会被视为已变更。例如,若因响应体过大而出现性能问题,可通过
config.structuralSharing标志禁用此功能。若你的查询响应中包含非 JSON 兼容的值,但仍希望检测数据是否变更,可提供自定义函数作为config.structuralSharing,用于根据旧响应和新响应计算值,并按需保留引用。
延伸阅读
请参阅我们的 社区资源(Community Resources) 中以下文章,进一步了解这些默认值: