重要默认值
开箱即用时,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或查询观察者(query observer)的活跃实例时,该结果会被标记为“非活跃”,并保留在缓存中,以便后续可能再次使用。默认情况下,“非活跃”查询将在 5 分钟后被垃圾回收。
若要更改此行为,你可以将查询的默认
gcTime修改为除5 * 60 * 1000毫秒以外的其他值。失败的查询会静默重试 3 次,并采用指数退避延迟,之后才捕获错误并在 UI 中显示。
若要更改此行为,你可以将查询的默认
retry和retryDelay选项修改为除3和默认指数退避函数以外的其他值。
- 查询结果默认采用结构共享(structural sharing),以检测数据是否真正发生变化;若未变化,则数据引用保持不变,从而更好地支持值稳定化。如果你对此概念不熟悉,也无需担心!99.9% 的情况下你无需禁用此功能,它能在零成本的前提下提升应用性能。
结构共享仅适用于 JSON 兼容的值;其他任何值类型均始终被视为已变更。例如,若因响应体过大而引发性能问题,可通过
config.structuralSharing标志禁用此功能。若你的查询响应中包含非 JSON 兼容的值,但仍需检测数据是否变更,可提供自定义函数作为config.structuralSharing,用于根据旧响应与新响应计算一个值,并按需保留引用。