资讯动态

TanStack Preact Query 的重要默认配置(Important Defaults)深度解析

发布时间:2026/9/10 4:35:21 来源:尧图企业网站定制
TanStack Preact Query 的重要默认配置Important Defaults深度解析【免费下载链接】query Powerful asynchronous state management, server-state utilities and data fetching for the web. TS/JS, React Query, Solid Query, Svelte Query and Vue Query.项目地址: https://gitcode.com/GitHub_Trending/qu/queryTanStack Preact Query 开箱即用但默认值往往是新用户踩坑与调试困难的源头缓存数据一律视为过期、失败静默重试 3 次、闲置查询 5 分钟后被回收……本指南以 docs/framework/preact/guides/important-defaults.md 为骨架逐条拆解 Preact Query 各项默认行为并结合仓库内tanstack/query-core源码给出实现依据与自定义方案。读完你将能熟练通过staleTime、gcTime、retry等选项掌控数据的过期、回收与重试节奏让请求行为完全符合预期。默认值设计哲学aggressive but saneTanStack Query 系列Preact Query、React Query、Vue Query、Solid Query 等共享同一套查询内核tanstack/query-core。在 Preact 应用中packages/preact-query/src/index.ts 直接export * from tanstack/query-core因此本文讨论的默认值行为在所有框架适配层上完全一致。这些默认值被官方定位为aggressive but sane激进但理智它们追求开箱即用即可获得合理体验但若使用者对其不了解往往会因出乎意料的自动行为而困惑。下文是每一个默认行为的完整盘点以及对应的调节入口。默认一缓存数据一经获取即视为 stale通过useQuery或useInfiniteQuery创建的查询实例默认会把缓存中已有的数据视为过期stale。这背后对应staleTime的默认值为0。其语义是只要新查询实例挂载、窗口重新聚焦或网络恢复库就会去后台重新请求以刷新数据。想要改变该行为可以全局或按查询设置staleTime。staleTime 的三种典型取值staleTime表示数据在多少毫秒内保持新鲜。设置了staleTime的查询在该时间到期前会被视为fresh新鲜设置staleTime: 2 * 60 * 10002 分钟内数据始终从缓存直接读取不会触发任何形式的 refetch除非查询被手动失效设置staleTime: Infinity永不因过期而触发 refetch直到查询被手动失效设置staleTime: static永不触发 refetch即使查询被手动失效也无效。static 与 Infinity 的关键差异static与Infinity都能阻止基于过期的自动 refetch但static更严格queryClient.invalidateQueries()可以失效staleTime: Infinity的查询但对staleTime: static的查询没有任何作用设置为always的refetchOnMount、refetchOnWindowFocus、refetchOnReconnect也一律被static阻止。该差异在源码中体现得非常直接。packages/query-core/src/query.ts 中isStaleByTime()的判定顺序是无数据视为 stale →static直接返回false永不 stale→ 已被 invalidated 视为 stale → 依据dataUpdatedAt与staleTime计算剩余新鲜时间。正因为static的短路判断位于 invalidated 判断之前失效操作对它无效。此外 query.ts 的isStatic()会检查当前观察者中是否存在staleTime: static的选项。选型建议static适合应用运行期间绝不可能变化的数据——启动时拉取的 feature flags、登录后加载的用户权限、静态参考表等Infinity适合仍然希望保留手动失效能力的数据。默认二stale 查询在三个时机自动后台刷新stale 查询会在以下时机被自动后台 refetch有新的查询实例挂载refetchOnMount生效窗口重新聚焦refetchOnWindowFocus生效网络重新连接refetchOnReconnect生效。设置更长的staleTime是避免过度 refetch 的推荐做法此外也可以直接定制这三个触发点例如将refetchOnWindowFocus设为false或always精细控制自动刷新的发生时机。其中refetchOnReconnect还有一个底层联动在 packages/query-core/src/queryClient.ts 中当它未显式定义时会被默认推导为networkMode ! always即网络模式下才在重连时刷新。三个触发点在query层同样有对应方法如 query.ts 的onFocus()、onOnline()分别由 focus 与在线状态管理器驱动。默认三refetchInterval 轮询与 staleTime 相互独立查询可选用refetchInterval选项周期性地触发 refetch它与staleTime是相互独立的两套机制——即使数据仍新鲜只要设置了refetchInterval就会按固定间隔轮询。具体用法详见 Polling轮询指南。默认四闲置查询保留 5 分钟后回收当某个查询不再有任何活跃实例useQuery、useInfiniteQuery或底层观察者都被卸载时它会被标记为inactive闲置但仍然留在缓存中以备后续再次使用。默认情况下闲置查询会在5 分钟后被垃圾回收garbage collected。对应源码是 packages/query-core/src/removable.ts 的updateGcTime()// Default to 5 minutes (Infinity for server-side) if no gcTime is set this.gcTime Math.max( this.gcTime || 0, newGcTime ?? (isServerEnvironment() ? Infinity : 5 * 60 * 1000), )值得注意的两点实现细节默认回收时长为1000 * 60 * 5毫秒即 5 分钟服务端环境SSR默认为Infinity避免回收尚未水合所需的数据回收时长取gcTime的最大值且调度逻辑removable.ts会先清除旧定时器再重新调度因此调大gcTime后旧数据不会立刻被误回收。如要改变该时长可将全局或单查询的gcTime改为其他毫秒值。例如对重新进入页面频率较高、希望更久地保留状态的查询设置gcTime: 30 * 60 * 1000。默认五失败查询静默重试 3 次指数退避查询失败时默认静默重试 3 次采用指数退避exponential backoff延迟全部重试失败后才把错误暴露给 UI。指数退避的实现在 packages/query-core/src/retryer.tsfunction defaultRetryDelay(failureCount: number) { return Math.min(1000 * 2 ** failureCount, 30000) }即第 1 次失败后等待约 2 秒2^1第 2 次约 4 秒依次递增并封顶 30 秒。若想改变可覆盖retry与retryDelay两个选项retry可设为false不重试、数字重试次数或(failureCount, error) boolean回调retryDelay可设为固定毫秒数或(failureCount, error) number自定义延迟函数实现线性退避、抖动jitter等策略。补充queryClient层面还提供缓存型默认值。queryClient.setQueryDefaults()会为特定queryKey注册默认选项例如对所有posts键的查询默认重试 5 次这些键级默认值会在defaultQueryOptions()中与全局默认、查询自身选项按优先级合并见下节。默认六结构共享Structural Sharing保持引用稳定查询结果默认启用结构共享structural sharing库会检测新数据与旧数据是否实质变化若未变化则保持原数据引用不变。这有助于配合useMemo、useCallback做值稳定化减少不必要的重渲染。初次接触该概念不必焦虑——绝大多数场景下无需关闭它它几乎以零成本提升应用性能。需要留意的边界与扩展结构共享仅对 JSON 兼容的值有效其他值类型如Date、自定义类实例、Map/Set 等永远被视为已变化若因响应体巨大等原因出现性能问题可通过structuralSharing: false关闭该特性类型定义见 packages/query-core/src/types.ts若响应中存在非 JSON 兼容值又希望正确判断是否变化可以传入自定义函数作为structuralSharing由它基于新旧响应计算并保留所需引用。如何在全局与单查询层面覆盖默认值无论是staleTime、gcTime、retry还是structuralSharing配置都有三层合并优先级最终由 queryClient.ts 的defaultQueryOptions()统一执行const defaultedOptions { ...this.#defaultOptions.queries, // ① QueryClient 全局默认 ...this.getQueryDefaults(options.queryKey), // ② 按 queryKey 的默认 ...options, // ③ 本次查询显式传入的选项 _defaulted: true, }全局配置示例import { QueryClient } from tanstack/preact-query export const queryClient new QueryClient({ defaultOptions: { queries: { staleTime: 5 * 60 * 1000, // 5 分钟内视为新鲜不重复请求 gcTime: 30 * 60 * 1000, // 闲置 30 分钟后回收 retry: 2, // 失败重试 2 次 refetchOnWindowFocus: false, structuralSharing: true, }, }, })按查询配置示例import { useQuery } from tanstack/preact-query // 该查询独享 2 分钟新鲜期且失败不重试 const { data } useQuery({ queryKey: [posts, id], queryFn: () fetchPost(id), staleTime: 2 * 60 * 1000, retry: false, }) // 只读的静态配置永不过期、无法被失效 const { data: flags } useQuery({ queryKey: [feature-flags], queryFn: () fetchFlags(), staleTime: static, })除useQuery外useInfiniteQuery、useSuspenseQuery以及tanstack/preact-query导出的queryOptions/infiniteQueryOptions帮助函数均支持同样的选项结构可查看 packages/preact-query/src/index.ts 的完整导出清单。默认值速查对照表默认行为默认值/时机相关选项如何调整缓存数据一经获取即视为 stalestaleTime: 0staleTime设为毫秒数、Infinity或static挂载新实例时后台刷新stale 即触发refetchOnMountfalse/always窗口聚焦时后台刷新stale 即触发refetchOnWindowFocusfalse/always网络重连时后台刷新stale 即触发refetchOnReconnectfalse/always默认受networkMode联动定时轮询不开启refetchInterval毫秒间隔与staleTime独立闲置查询回收inactive 后5 分钟gcTime其他毫秒值SSR 下默认为Infinity失败静默重试3 次指数退避retry/retryDelay次数、布尔或自定义策略函数结构共享默认开启structuralSharingfalse或自定义比较函数默认值对调试心态的启示文档在开头特别强调这些默认值会在用户不知情时让学习与调试变难。实践中两个高频惊吓点分别是我没有写 refetch 代码为什么页面一聚焦数据就变了——实为refetchOnWindowFocus配合默认staleTime: 0在起作用请求明明失败了为什么 UI 迟迟不报错——实为默认重试 3 次 指数退避在按 2s/4s/8s 静默重试。理解了本文的默认值体系后这两类现象都可被准确预判。关于缓存失效与手动刷新之间的关系可继续阅读 Query Invalidation 指南 与 Caching 指南 获取完整图景。该指南页面本身由官方文档生成机制从 React 版源文档 派生社区深入讨论还可参见 Community Resources。【免费下载链接】query Powerful asynchronous state management, server-state utilities and data fetching for the web. TS/JS, React Query, Solid Query, Svelte Query and Vue Query.项目地址: https://gitcode.com/GitHub_Trending/qu/query创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价