此对比表力求尽可能准确和公正。如果您使用这些库中的任何一个,并且认为信息可以改进,请随时使用本页底部的“在 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, Any (Reactive Variables) | Promise, REST, GraphQL | Promise, REST, GraphQL |
| 支持的框架 | React | React | React + 其他 | Any | React |
| 缓存策略 | 分层键 -> 值 | 唯一键 -> 值 | 规范化模式 | 唯一键 -> 值 | 嵌套路由 -> 值 |
| 缓存键策略 | JSON | JSON | GraphQL 查询 | JSON | 路由路径 |
| 缓存变更检测 | 深比较键 (稳定序列化) | 深比较键 (稳定序列化) | 深比较键 (不稳定序列化) | 键引用相等 (===) | 路由变更 |
| 数据变更检测 | 深比较 + 结构共享 | 深比较 (通过 stable-hash) | 深比较 (不稳定序列化) | 键引用相等 (===) | 加载器运行 |
| 数据记忆化 | 完全结构共享 | 标识 (===) | 规范化标识 | 标识 (===) | 标识 (===) |
| 包大小 | |||||
| API 定义位置 | 组件, 外部配置 | 组件 | GraphQL 模式 | 外部配置 | 路由树配置 |
| 查询 | ✅ | ✅ | ✅ | ✅ | ✅ |
| 缓存持久化 | ✅ | ✅ | ✅ | ✅ | 🛑 仅活动路由 8 |
| 开发者工具 | ✅ | ✅ | ✅ | ✅ | 🛑 |
| 轮询/间隔 | ✅ | ✅ | ✅ | ✅ | 🛑 |
| 并行查询 | ✅ | ✅ | ✅ | ✅ | ✅ |
| 依赖查询 | ✅ | ✅ | ✅ | ✅ | ✅ |
| 分页查询 | ✅ | ✅ | ✅ | ✅ | ✅ |
| 无限查询 | ✅ | ✅ | ✅ | ✅ | 🛑 |
| 双向无限查询 | ✅ | 🔶 | 🔶 | ✅ | 🛑 |
| 无限查询重新获取 | ✅ | ✅ | 🛑 | ✅ | 🛑 |
| 延迟查询数据1 | ✅ | ✅ | ✅ | ✅ | ✅ |
| 选择器 | ✅ | 🛑 | ✅ | ✅ | 不适用 |
| 初始数据 | ✅ | ✅ | ✅ | ✅ | ✅ |
| 滚动恢复 | ✅ | ✅ | ✅ | ✅ | ✅ |
| 缓存操作 | ✅ | ✅ | ✅ | ✅ | 🛑 |
| 过期查询丢弃 | ✅ | ✅ | ✅ | ✅ | ✅ |
| 渲染批处理和优化2 | ✅ | ✅ | 🛑 | ✅ | ✅ |
| 自动垃圾回收 | ✅ | 🛑 | 🛑 | ✅ | 不适用 |
| 变更钩子 | ✅ | ✅ | ✅ | ✅ | ✅ |
| 离线变更支持 | ✅ | 🛑 | 🟡 | 🛑 | 🛑 |
| 预取 API | ✅ | ✅ | ✅ | ✅ | ✅ |
| 查询取消 | ✅ | 🛑 | 🛑 | 🛑 | ✅ |
| 部分查询匹配3 | ✅ | 🔶 | ✅ | ✅ | 不适用 |
| Stale While Revalidate | ✅ | ✅ | ✅ | ✅ | 🛑 |
| Stale Time 配置 | ✅ | 🛑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 提供的模式)以及帮助库识别该模式中各个实体和实体类型的启发式方法。
6 规范化缓存 - React Query、SWR 和 RTK-Query 目前不支持自动规范化缓存,该缓存描述了在平面体系结构中存储实体以避免某些高级别数据重复。
7 SWR 的不可变模式 - SWR 附带一个“不可变”模式,它确实允许您在缓存的生命周期内仅获取一次查询,但它仍然没有 stale-time 或条件自动重新验证的概念
8 React Router 缓存持久性 - React Router 不会缓存超出当前匹配路由的数据。如果离开路由,其数据将丢失。