此比较表格力求尽可能准确和公正。如果您使用过其中任何一个库,并认为信息可以改进,请随时使用此页面底部的“在 Github 上编辑此页”链接建议更改(附上说明或声明证据)。
功能/特性说明
React Query | SWR (网站) | Apollo Client (网站) | RTK-Query (网站) | React Router (网站) | |
---|---|---|---|---|---|
Github 仓库 / Stars | |||||
平台要求 | React | React | React, GraphQL | Redux | React |
它们的比较 | (无) | (无) | 比较 | (无) | |
支持的查询语法 | Promise, REST, GraphQL | Promise, REST, GraphQL | GraphQL, 任意 (响应式变量) | Promise, REST, GraphQL | Promise, REST, GraphQL |
支持的框架 | React | React | React + 其他 | 任意 | React |
缓存策略 | 分层键 -> 值 | 唯一键 -> 值 | 标准化模式 | 唯一键 -> 值 | 嵌套路由 -> 值 |
缓存键策略 | JSON | JSON | GraphQL 查询 | JSON | 路由路径 |
缓存变更检测 | 深度比较键 (稳定序列化) | 深度比较键 (稳定序列化) | 深度比较键 (不稳定序列化) | 键引用相等 (===) | 路由变更 |
数据变更检测 | 深度比较 + 结构共享 | 深度比较 (通过 stable-hash) | 深度比较 (不稳定序列化) | 键引用相等 (===) | Loader 运行 |
数据记忆化 | 完全结构共享 | 恒等 (===) | 标准化恒等 | 恒等 (===) | 恒等 (===) |
Bundle 大小 | |||||
API 定义位置 | 组件,外部配置 | 组件 | GraphQL 模式 | 外部配置 | 路由树配置 |
查询 | ✅ | ✅ | ✅ | ✅ | ✅ |
缓存持久化 | ✅ | ✅ | ✅ | ✅ | 🛑 仅限活动路由 8 |
Devtools | ✅ | ✅ | ✅ | ✅ | 🛑 |
轮询/间隔 | ✅ | ✅ | ✅ | ✅ | 🛑 |
并行查询 | ✅ | ✅ | ✅ | ✅ | ✅ |
依赖查询 | ✅ | ✅ | ✅ | ✅ | ✅ |
分页查询 | ✅ | ✅ | ✅ | ✅ | ✅ |
无限查询 | ✅ | ✅ | ✅ | 🛑 | 🛑 |
双向无限查询 | ✅ | 🔶 | 🔶 | 🛑 | 🛑 |
无限查询重新获取 | ✅ | ✅ | 🛑 | 🛑 | 🛑 |
滞后查询数据1 | ✅ | ✅ | ✅ | ✅ | ✅ |
选择器 | ✅ | 🛑 | ✅ | ✅ | 不适用 |
初始数据 | ✅ | ✅ | ✅ | ✅ | ✅ |
滚动恢复 | ✅ | ✅ | ✅ | ✅ | ✅ |
缓存操作 | ✅ | ✅ | ✅ | ✅ | 🛑 |
过时查询忽略 | ✅ | ✅ | ✅ | ✅ | ✅ |
渲染批处理 & 优化2 | ✅ | ✅ | 🛑 | ✅ | ✅ |
自动垃圾回收 | ✅ | 🛑 | 🛑 | ✅ | 不适用 |
突变 Hook | ✅ | ✅ | ✅ | ✅ | ✅ |
离线突变支持 | ✅ | 🛑 | 🟡 | 🛑 | 🛑 |
预取 API | ✅ | ✅ | ✅ | ✅ | ✅ |
查询取消 | ✅ | 🛑 | 🛑 | 🛑 | ✅ |
部分查询匹配3 | ✅ | 🔶 | ✅ | ✅ | 不适用 |
Stale While Revalidate | ✅ | ✅ | ✅ | ✅ | 🛑 |
Stale Time 配置 | ✅ | 🛑7 | 🛑 | ✅ | 🛑 |
预使用查询/突变配置4 | ✅ | 🛑 | ✅ | ✅ | ✅ |
窗口聚焦时重新获取 | ✅ | ✅ | 🛑 | ✅ | 🛑 |
网络状态重新获取 | ✅ | ✅ | ✅ | ✅ | 🛑 |
通用缓存脱水/补水 | ✅ | 🛑 | ✅ | ✅ | ✅ |
离线缓存 | ✅ | 🛑 | ✅ | 🔶 | 🛑 |
React Suspense | ✅ | ✅ | ✅ | 🛑 | ✅ |
抽象/不可知核心 | ✅ | 🛑 | ✅ | ✅ | 🛑 |
突变后自动重新获取5 | 🔶 | 🔶 | ✅ | ✅ | ✅ |
标准化缓存6 | 🛑 | 🛑 | ✅ | 🛑 | 🛑 |
1 滞后查询数据 - React Query 提供了一种在加载下一个查询时继续查看现有查询数据的方法(类似于 suspense 即将原生提供的相同用户体验)。这在编写分页 UI 或无限加载 UI 时非常重要,在这些 UI 中,您不希望在请求新查询时显示硬加载状态。其他库没有此功能,并且在新查询加载时(除非已预取)为新查询呈现硬加载状态。
2 渲染优化 - React Query 具有出色的渲染性能。默认情况下,它会自动跟踪访问了哪些字段,并且仅在其中一个字段发生更改时才重新渲染。如果您想选择退出此优化,将
notifyOnChangeProps
设置为'all'
将在查询更新时重新渲染您的组件。例如,因为它有新数据,或者指示它正在获取数据。React Query 还会将更新批量处理在一起,以确保当多个组件使用同一查询时,您的应用程序仅重新渲染一次。如果您只对data
或error
属性感兴趣,您可以通过将notifyOnChangeProps
设置为['data', 'error']
来进一步减少渲染次数。
3 部分查询匹配 - 因为 React Query 使用确定性的查询键序列化,这允许您操作查询的变量组,而无需知道您要匹配的每个单独的查询键,例如,您可以重新获取每个在其键中以
todos
开头的查询,而不管变量如何,或者您可以使用(或不使用)变量或嵌套属性来定位特定查询,甚至可以使用过滤器函数来仅匹配满足您特定条件的查询。
4 预使用查询配置 - 这只是一个花哨的名称,用于能够在查询和突变使用之前配置它们的行为方式。例如,可以预先完全配置查询的默认值,当需要使用它时,只需要
useQuery({ queryKey })
,而不是每次使用时都必须传递 fetcher 和/或选项。SWR 确实具有此功能的局部形式,允许您预先配置默认 fetcher,但仅作为全局 fetcher,而不是在每个查询的基础上,并且绝对不适用于突变。
5 突变后自动重新获取 - 为了在发生突变后真正实现自动重新获取,需要一个模式(例如 graphQL 提供的模式)以及帮助库知道如何在模式中识别单个实体和实体类型的启发式方法。
6 标准化缓存 - React Query、SWR 和 RTK-Query 目前不支持自动标准化缓存,该缓存描述了将实体存储在扁平架构中以避免一些高级别的数据重复。
7 SWR 的不可变模式 - SWR 附带一个“不可变”模式,该模式确实允许您在缓存的生命周期内仅获取一次查询,但它仍然没有过时时间或条件自动重新验证的概念
8 React Router 缓存持久性 - React Router 不会缓存超出当前匹配路由的数据。如果离开路由,其数据将丢失。