框架
版本

比较 | React Query vs SWR vs Apollo vs RTK Query vs React Router

此比较表力求尽可能准确和公正。如果您使用这些库中的任何一个,并觉得信息可以改进,请随时使用本页面底部的“在 Github 上编辑此页面”链接提出更改建议(附注或证据)。

特性/功能键

  • ✅ 一等、内置,无需额外配置或代码即可使用
  • 🟡 支持,但作为非官方的第三方或社区库/贡献
  • 🔶 支持并有文档,但需要额外的用户代码来实现
  • 🛑 未正式支持或记录。
React QuerySWR (网站)Apollo Client (网站)RTK-Query (网站)React Router (网站)
Github 仓库 / 星星数
平台要求ReactReactReact, GraphQLReduxReact
他们的比较(无)(无)比较(无)
支持的查询语法Promise, REST, GraphQLPromise, REST, GraphQLGraphQL, 任何(响应式变量)Promise, REST, GraphQLPromise, REST, GraphQL
支持的框架ReactReactReact + 其他任何React
缓存策略分层键 -> 值唯一键 -> 值规范化 Schema唯一键 -> 值嵌套路由 -> 值
缓存键策略JSONJSONGraphQL QueryJSON路由路径
缓存更改检测深度比较键(稳定序列化)深度比较键(稳定序列化)深度比较键(不稳定序列化)键引用相等(===)路由更改
数据更改检测深度比较 + 结构共享深度比较(通过 stable-hash深度比较(不稳定序列化)键引用相等(===)Loader 运行
数据记忆化完全结构共享标识(===)规范化标识标识(===)标识(===)
打包大小 +
API 定义位置组件,外部配置组件GraphQL Schema外部配置路由树配置
查询
缓存持久化🛑 仅活动路由 8
开发工具🛑
轮询/间隔🛑
并行查询
依赖查询
分页查询
无限查询🛑
双向无限查询🔶🔶🛑
无限查询重新获取🛑🛑
滞后查询数据1
选择器🛑不适用
初始数据
滚动恢复
缓存操作🛑
废弃查询清除
渲染批处理和优化2🛑
自动垃圾回收🛑🛑不适用
Mutation Hooks
离线 Mutation 支持🛑🟡🛑🛑
预取 API
查询取消🛑🛑🛑
部分查询匹配3🔶不适用
Stale While Revalidate(过时重新验证)🛑
Stale Time 配置🛑7🛑🛑
预使用查询/Mutation 配置4🛑
窗口焦点重新获取🛑🛑
网络状态重新获取🛑
通用缓存脱水/再水化🛑
离线缓存🛑🔶🛑
React Suspense🛑
抽象/无关核心🛑🛑
Mutation 后自动重新获取5🔶🔶
规范化缓存6🛑🛑🛑🛑

注意事项

1 滞后查询数据 - React Query 提供了一种在下一个查询加载时继续查看现有查询数据的方法(类似于 Suspense 即将原生提供的相同用户体验)。这在编写分页 UI 或无限加载 UI 时非常重要,因为您不希望在请求新查询时显示硬加载状态。其他库没有此功能,并在新查询加载时为新查询渲染硬加载状态(除非已预取)。

2 渲染优化 - React Query 具有出色的渲染性能。默认情况下,它会自动跟踪访问的字段,并且仅当其中一个字段发生更改时才重新渲染。如果您想选择退出此优化,将 notifyOnChangeProps 设置为 'all' 将在查询更新时重新渲染您的组件。例如,因为它有新数据,或者指示它正在获取。React Query 还将更新批处理在一起,以确保当多个组件使用相同的查询时,您的应用程序只重新渲染一次。如果您只对 dataerror 属性感兴趣,您可以通过将 notifyOnChangeProps 设置为 ['data', 'error'] 来进一步减少渲染次数。

3 部分查询匹配 - 因为 React Query 使用确定性查询键序列化,这允许您操作可变查询组,而无需知道您想要匹配的每个单独的查询键,例如,您可以重新获取其键以 todos 开头的每个查询,无论变量如何,或者您可以使用(或不使用)变量或嵌套属性来定位特定查询,甚至可以使用筛选函数仅匹配通过您的特定条件的查询。

4 预使用查询配置 - 这只是一个花哨的名称,指能够在查询和 mutation 使用之前配置它们的行为方式。例如,查询可以预先完全配置默认值,当需要使用它时,只需 useQuery({ queryKey }),而无需在每次使用时传递 fetcher 和/或选项。SWR 具有此功能的部分形式,允许您预配置默认 fetcher,但仅作为全局 fetcher,而不是按查询基础,当然也不是用于 mutation。

5 Mutation 后自动重新获取 - 为了在 mutation 发生后实现真正的自动重新获取,需要一个 schema(例如 GraphQL 提供的 schema)以及有助于库知道如何在该 schema 中识别单个实体和实体类型的启发式方法。

6 规范化缓存 - React Query、SWR 和 RTK-Query 目前不支持自动规范化缓存,它描述了以扁平架构存储实体,以避免一些高级别的数据重复。

7 SWR 的不可变模式 - SWR 附带了一个“不可变”模式,它确实允许您在缓存的生命周期内只获取一次查询,但它仍然没有 stale-time 或条件自动重新验证的概念。

8 React Router 缓存持久化 - React Router 不会缓存超出当前匹配路由的数据。如果路由被离开,其数据将丢失。