React Query Best Practices
重要提示:本指南针对 React Query v4,部分模式在 v5 中可能有所不同。
这是一份面向 React Query v4(TanStack Query)的综合指南,基于 TkDodo 的权威博客系列。包含 7 个类别共 24 条规则,并按影响程度区分优先级。
何时应用
在以下情况参考这些准则:
实现新的查询或变更 将 WebSocket 与 React Query 集成 设置查询失效模式 调试 React Query 行为 优化渲染性能 TypeScript 集成相关问题
按优先级划分的规则类别
优先级 1:查询键与模式(关键),前缀 query-
- query-keys-as-dependencies:在 queryKey 中包含所有 queryFn 参数
- query-key-factory:使用工厂模式生成一致的键
- query-select-transforms:使用 select 选项进行数据转换
- query-status-check-order:先检查 data,再检查 error,最后检查 loading
- query-tracked-properties:只解构你实际使用的属性
- query-placeholder-vs-initial:了解何时使用这两种方式
- query-dependent-enabled:使用 enabled 选项处理依赖查询
优先级 2:变更与更新(关键),前缀 mutation-
- mutation-prefer-mutate:优先使用带回调的 mutate() 而非 mutateAsync()
- mutation-invalidation:变更后使查询失效
- mutation-direct-cache-update:在合适时直接更新缓存
- mutation-optimistic-updates:立即显示成功,失败时回滚
- mutation-callback-separation:查询逻辑放在 hook 中,UI 效果放在组件中
优先级 3:缓存策略(高),前缀 cache-
- cache-stale-time:为你的领域设置合适的 staleTime
- cache-refetch-triggers:在生产环境中保持 refetch 触发器启用
优先级 4:WebSocket 集成(高),前缀 websocket-
- websocket-event-invalidation:使用事件触发失效
- websocket-stale-time-infinity:对由 WS 管理的数据设置 staleTime: Infinity
- websocket-reconnection:重新连接时使过期查询失效
优先级 5:TypeScript 集成(中),前缀 typescript-
- typescript-infer-dont-specify:让 TypeScript 推断,为 queryFn 标注类型
- typescript-zod-validation:使用 Zod 进行运行时验证
优先级 6:测试模式(中),前缀 testing-
- testing-fresh-client:每个测试创建新的 QueryClient
- testing-msw-mocking:使用 MSW 进行网络模拟
优先级 7:常见陷阱(中),前缀 troubleshoot-
- troubleshoot-copy-to-state:切勿将查询数据复制到本地 state
- troubleshoot-missing-key-deps:在查询键中包含所有依赖
- troubleshoot-fetch-not-reject:使用 fetch 处理 HTTP 错误
优先级 8:迁移到 v5(高),前缀 migration-
- migration-single-signature:所有 hook 现在接受单个对象参数
- migration-status-pending:status 'loading' 改为 'pending';isLoading 语义有变化
- migration-cache-time-to-gc-time:cacheTime 重命名为 gcTime
- migration-keep-previous-data:keepPreviousData 改为带恒等函数的 placeholderData
- migration-query-callbacks-removed:从 useQuery 中移除 onSuccess/onError/onSettled
- migration-suspense-hooks:新增 useSuspenseQuery、useSuspenseInfiniteQuery hook
- migration-throw-on-error:useErrorBoundary 重命名为 throwOnError
- migration-remove-method:移除 query.remove();改用 queryClient.removeQueries()
- migration-initial-page-param:无限查询现在要求 initialPageParam
- migration-refetch-page-to-max-pages:refetchPage 被 maxPages 取代
- migration-hydration-boundary:Hydrate 组件重命名为 HydrationBoundary
- migration-refetch-interval-callback:refetchInterval 回调现在只接收 query
- migration-context-to-query-client:移除 context 属性;直接传入 queryClient
- migration-misc-breaking-changes:React 18 最低要求、服务器 retry=0、hashKey、isDataEqual 等
核心心智模型
React Query 不是数据获取库——它是异步状态管理器 服务器状态不等于客户端状态——切勿在全局状态管理器中混合它们 Stale-while-revalidate——立即显示缓存数据,在后台获取 查询键即依赖——包含 queryFn 中使用的所有变量
如何使用
阅读单独的规则文件获取详细说明和代码示例: rules/query-key-factory.md rules/mutation-invalidation.md rules/websocket-event-invalidation.md
每个规则文件包含: 为什么重要的简要说明 错误代码示例 正确代码示例
完整编译文档 如需展开所有规则的完整指南:AGENTS.md