React Query
React Query
Motivation
开箱即用的
- 在一个你不控制或不拥有的地方被远程持久化
- 需要异步的
API 来获取和更新 - 意味着共享所有权,可以在你不知情的情况下被其他人改变
- 如果你不小心,有可能在你的应用程序中变得过时。
一旦你掌握了应用程序中服务器状态的性质,甚至更多的挑战会随着你的发展而出现,比如说。
- 缓存…
( 可能是编程中最难做到的事情) - 将对同一数据的多个请求简化为一个请求
- 在后台更新过时的数据
- 知道数据何时过期
- 尽可能快地反映数据的更新
- 性能优化,如分页和懒惰加载数据
- 管理内存和服务器状态的垃圾收集
- 用结构共享来记忆查询结果
如果你没有被这个清单压倒,那么这一定意味着你可能已经解决了所有的服务器状态问题,并应该获得奖励。然而,如果你像绝大多数人一样,你要么还没有解决所有这些挑战,要么还没有解决大部分挑战,而我们只是在抓紧时间。
- 帮助你从你的应用程序中删除许多复杂的和被误解的代码,只用少数几行
React Query 逻辑来代替。 - 使你的应用程序更易维护,更容易建立新的功能,而不必担心新的服务器状态数据源的接线问题
- 通过使你的应用程序感觉比以前更快、更灵敏,对你的终端用户产生直接影响。
- 潜在地帮助你节省带宽和提高内存性能
对比
Comparsion | React Query | SWR (Website) | Apollo Client (Website) | RTK-Query (Website) |
---|---|---|---|---|
Github Repo / Stars |
|
|
|
|
Platform Requirements | React | React | React, GraphQL | Redux |
Their Comparison | (none) | (none) | Comparison | |
Supported Query Syntax | Promise, REST, GraphQL | Promise, REST, GraphQL | GraphQL | Promise, REST, GraphQL |
Supported Frameworks | React | React | React + Others | Any |
Supported Query Keys | JSON | JSON | GraphQL Query | JSON |
Query Key Change Detection | Deep Compare (Stable Serialization) | Referential Equality (===) | Deep Compare (Unstable Serialization) | Referential Equality (===) |
Query Data Memoization Level | Query + Structural Sharing | Query | Query + Entity + Structural Sharing | Query |
Bundle Size |
|
|
|
|
API Definition | On-Use, Declarative | On-Use | GraphQL Schema | Declarative |
Queries | ✅ | ✅ | ✅ | ✅ |
Caching | ✅ | ✅ | ✅ | ✅ |
Devtools | ✅ | 🟡 | ✅ | ✅ |
Polling/Intervals | ✅ | ✅ | ✅ | ✅ |
Parallel Queries | ✅ | ✅ | ✅ | ✅ |
Dependent Queries | ✅ | ✅ | ✅ | ✅ |
Paginated Queries | ✅ | ✅ | ✅ | ✅ |
Infinite Queries | ✅ | ✅ | ✅ | 🛑 |
Bi-directional Infinite Queries | ✅ | 🔶 | 🔶 | 🛑 |
Infinite Query Refetching | ✅ | ✅ | 🛑 | 🛑 |
Lagged Query Data1 | ✅ | 🛑 | 🛑 | ✅ |
Selectors | ✅ | 🛑 | ✅ | ✅ |
Initial Data | ✅ | ✅ | ✅ | ✅ |
Scroll Recovery | ✅ | ✅ | ✅ | ✅ |
Cache Manipulation | ✅ | ✅ | ✅ | ✅ |
Outdated Query Dismissal | ✅ | ✅ | ✅ | ✅ |
Render Optimization2 | ✅ | 🛑 | 🛑 | ✅ |
Auto Garbage Collection | ✅ | 🛑 | 🛑 | ✅ |
Mutation Hooks | ✅ | 🟡 | ✅ | ✅ |
Offline Mutation Support | ✅ | 🛑 | 🟡 | 🛑 |
Prefetching APIs | ✅ | 🔶 | ✅ | ✅ |
Query Cancellation | ✅ | 🛑 | 🛑 | 🛑 |
Partial Query Matching3 | ✅ | 🛑 | 🛑 | ✅ |
Stale While Revalidate | ✅ | ✅ | ✅ | ✅ |
Stale Time Configuration | ✅ | 🛑 | 🛑 | ✅ |
Pre-usage Query/Mutation Configuration4 | ✅ | 🛑 | 🛑 | ✅ |
Window Focus Refetching | ✅ | ✅ | 🛑 | 🔶 |
Network Status Refetching | ✅ | ✅ | ✅ | 🔶 |
General Cache Dehydration/Rehydration | ✅ | 🛑 | ✅ | ✅ |
Offline Caching | ✅ (Experimental) | 🛑 | ✅ | 🔶 |
React Suspense (Experimental) | ✅ | ✅ | 🛑 | 🛑 |
Abstracted/Agnostic Core | ✅ | 🛑 | ✅ | ✅ |
Automatic Refetch after Mutation5 | 🔶 | 🔶 | ✅ | ✅ |
Normalized Caching6 | 🛑 | 🛑 | ✅ | 🛑 |
Hello World
import { QueryClient, QueryClientProvider, useQuery } from "react-query";
const queryClient = new QueryClient();
export default function App() {
return (
<QueryClientProvider client={queryClient}>
<Example />
</QueryClientProvider>
);
}
function Example() {
const { isLoading, error, data } = useQuery("repoData", () =>
fetch("https://api.github.com/repos/tannerlinsley/react-query").then(
(res) => res.json()
)
);
if (isLoading) return "Loading...";
if (error) return "An error has occurred: " + error.message;
return (
<div>
<h1>{data.name}</h1>
<p>{data.description}</p>
<strong>👀 {data.subscribers_count}</strong>{" "}
<strong>✨ {data.stargazers_count}</strong>{" "}
<strong>🍴 {data.forks_count}</strong>
</div>
);
}
如果希望在类组件中使用,可以采取如下方式:
function UseQuery(props) {
return props.children(useQuery(props.key, props.fn, props.options))
}
<UseQuery
key=“todos”
fn={() => getTodos()}
options={{ staleTime: 5000 }}
>
{query => {. . .}}
</UseQuery>