译零 TransZero · TanStack Query 中文文档
主站

对比:React Query 与 SWR、Apollo、RTK Query 及 React Router

更新于 2026-11-02 React 查看英文原文 ↗

本对比表格力求尽可能准确、客观。如果你正在使用其中任一库,并认为信息有待完善,欢迎通过本页底部的「在 GitHub 上编辑此页面」链接提出修改建议(请附上说明或相关依据)。

功能/能力标识说明:

  • ✅ 一级支持:开箱即用,无需额外配置或代码
  • 🟡 社区支持:由第三方或社区提供非官方支持
  • 🔶 已支持且有文档说明,但需用户自行编写额外代码实现
  • 🛑 官方未支持,亦无相关文档。
React Query SWR (官网) Apollo Client (官网) RTK-Query (官网) React Router (官网)
GitHub 仓库 / Star 数
平台要求 React React React、GraphQL Redux React
各自的对比文档 (无) (无) 对比文档 (无)
支持的查询语法 Promise、REST、GraphQL Promise、REST、GraphQL GraphQL、任意(响应式变量) Promise、REST、GraphQL Promise、REST、GraphQL
支持的框架 React React React 及其他 任意 React
缓存策略 层级化键 → 值 唯一键 → 值 规范化 Schema 唯一键 → 值 嵌套路由 → 值
缓存键策略 JSON JSON GraphQL 查询 JSON 路由路径
缓存变更检测 深度比较键(稳定序列化) 深度比较键(稳定序列化) 深度比较键(不稳定序列化) 键引用相等性(===) 路由变更
数据变更检测 深度比较 + 结构共享 深度比较(通过 stable-hash) 深度比较(不稳定序列化) 键引用相等性(===) Loader 执行
数据记忆化 完整结构共享 引用相等性(===) 规范化引用相等性 引用相等性(===) 引用相等性(===)
包体积 +
API 定义位置 组件内、外部配置 组件内 GraphQL Schema 外部配置 路由树配置
查询 ✅ ✅ ✅ ✅ ✅
缓存持久化 ✅ ✅ ✅ ✅ 🛑 仅活跃路由 8
开发者工具 ✅ ✅ ✅ ✅ 🛑
轮询 / 间隔 ✅ ✅ ✅ ✅ 🛑
并行查询 ✅ ✅ ✅ ✅ ✅
依赖查询 ✅ ✅ ✅ ✅ ✅
分页查询 ✅ ✅ ✅ ✅ ✅
无限查询 ✅ ✅ ✅ ✅ 🛑
双向无限查询 ✅ 🔶 🔶 ✅ 🛑
无限查询重新拉取 ✅ ✅ 🛑 ✅ 🛑
滞后查询数据1 ✅ ✅ ✅ ✅ ✅
选择器 ✅ 🛑 ✅ ✅ N/A
初始数据 ✅ ✅ ✅ ✅ ✅
滚动恢复 ✅ ✅ ✅ ✅ ✅
缓存操作 ✅ ✅ ✅ ✅ 🛑
过期查询自动清除 ✅ ✅ ✅ ✅ ✅
渲染批处理与优化2 ✅ ✅ 🛑 ✅ ✅
自动垃圾回收 ✅ 🛑 🛑 ✅ N/A
修改 Hook ✅ ✅ ✅ ✅ ✅
离线修改支持 ✅ 🛑 🟡 🛑 🛑
预取 API ✅ ✅ ✅ ✅ ✅
查询取消 ✅ 🛑 🛑 🛑 ✅
部分查询匹配3 ✅ 🔶 ✅ ✅ N/A
过期时重新验证(Stale-while-revalidate) ✅ ✅ ✅ ✅ 🛑
过期时间(staleTime)配置 ✅ 🛑7 🛑 ✅ 🛑
使用前的查询/修改预配置4 ✅ 🛑 ✅ ✅ ✅
窗口焦点触发重新拉取 ✅ ✅ 🛑 ✅ 🛑
网络状态变化触发重新拉取 ✅ ✅ ✅ ✅ 🛑
通用缓存脱水/注水 ✅ 🛑 ✅ ✅ ✅
离线缓存 ✅ 🛑 ✅ 🔶 🛑
React Suspense ✅ ✅ ✅ 🛑 ✅
抽象化/无关平台核心 ✅ 🛑 ✅ ✅ 🛑
修改后自动重新拉取5 🔶 🔶 ✅ ✅ ✅
规范化缓存6 🛑 🛑 ✅ 🛑 🛑

注释

1 滞后查询数据 — React Query 提供一种机制,允许你在下一次查询加载期间继续显示当前查询的数据(其用户体验类似于 Suspense 即将原生提供的能力)。这在构建分页 UI 或无限加载 UI 时极为关键:你无需在每次发起新查询时都展示硬性的加载状态。其他库不具备该能力,除非提前预取,否则会在新查询加载期间强制渲染硬性加载状态。

2 渲染优化 — React Query 具备出色的渲染性能。默认情况下,它会自动追踪组件访问了哪些字段,并仅在这些字段之一发生变化时才触发重新渲染。若希望禁用该优化,可将 notifyOnChangeProps 设为 'all',使组件在查询更新(例如获得新数据或进入拉取状态)时始终重新渲染。此外,React Query 会将多个更新合并为一次批量更新,确保当多个组件共用同一查询时,应用仅重新渲染一次。如果你只关心 data 或 error 属性,还可进一步减少渲染次数:将 notifyOnChangeProps 设为 ['data', 'error']。

3 部分查询匹配 — 由于 React Query 使用确定性的查询键序列化方式,因此你可在无需知晓每个具体查询键的前提下,对一组变量化的查询进行操作。例如,你可以重新拉取所有以 todos 开头的查询(忽略其变量),也可精准定位含(或不含)特定变量或嵌套属性的查询,甚至可通过过滤函数,仅匹配满足你自定义条件的查询。

4 使用前的查询配置 — 此术语指在查询或修改实际被调用前,预先定义其行为的能力。例如,你可预先为某查询完整配置默认选项;待真正使用时,只需传入 useQuery({ queryKey }) 即可,而无需每次都重复传递拉取器和/或选项。SWR 仅支持一种有限形式:允许全局预设默认拉取器,但不支持按查询粒度配置,更不支持为修改做类似配置。

5 修改后自动重新拉取 — 若要实现真正的自动重新拉取,需要具备模式定义(如 GraphQL 提供的 Schema)以及配套启发式规则,帮助库识别模式中各个实体及其类型。

6 规范化缓存 — React Query、SWR 和 RTK-Query 当前均不支持自动规范化缓存,即无法将实体扁平化存储以避免高层级数据冗余。

7 SWR 的不可变模式 — SWR 提供“不可变”模式,允许查询在其缓存生命周期内仅拉取一次;但它仍不支持过期时间(staleTime)概念,也不支持条件式自动再验证。

8 React Router 缓存持久化 — React Router 不会缓存当前匹配路由之外的数据。一旦离开某路由,其对应数据即被丢弃。

本页为 TanStack Query 文档(React 版)的非官方中文翻译,原文由上游团队维护,遵循 MIT 许可。 译文如有偏差,以英文原文为准。

译自上游 59d11de