该系列其他文章可以点击查看专栏👉🏻👉🏻react-query手把手教程系列
介绍
在react-query中开发者可以通过访问isLoading
状态,为用户展示loading动画。第一次加载数据完成后,react-query将会把数据存在缓存中,多数情况下就不必再次显示loading动画。
但是react-query也会在后台通过策略自动重新获取数据。在某些情况下,用户可能会想知道这些数据是否正在被后台刷新,此时你就需要isFetching
属性。在第一次加载及后面刷新的加载过程中,该属性的值为true
实践
isFetching
可以通过在当前数据的旁边添加一个指示器,表示正在获取后端数据。伪代码如下:
import { Spin, Space } from 'antd';
const User = ({userId}) => {
const userQuery = useQuery(
["user", userId],
(userId) => fetchUser(userId),
);
// ①
if (userQuery.isLoading) {
return <Spin />;
}
return (
<Space>
<h1>
<span>{userQuery.data.name}</span>
{userQuery.isFetching && <Spin />}
</h1>
<p>{userQuery.data.email}</p>
</Space>
)
}
由于第一次加载数据时,没有任何数据,此时①只展示加载动画。
在②中由于缓存中已经存储了用户数据,只是在后台重新刷新数据时,在用户名的旁边为用户展示正在获取数据的小动画,并不影响之前缓存数据的展示。
useIsFetching
获取全局isFetching
数据
上面介绍的仅仅是单个查询中,获取当前请求的isFetching
状态,如果需要进行批量查询,那么就需要使用useIsFetching
钩子。
如果你需要一个组件来显示,当前全局是否有后台数据正在获取,可以用下面的例子:
import { Spin } from 'antd';
const QueryLoader = () => {
const isFetching = useIsFetching();
if (isFetching) {
return <Spin />
}
return null;
}
export default QueryLoader
接着需要在根组件中(index.js/index.tsx
)添加该指示器:
import ReactDOM from "react-dom";
import { QueryClient, QueryClientProvider } from "react-query";
import App from "./App";
const queryClient = new QueryClient();
const rootElement = document.getElementById("root");
const root = ReactDOM.createRoot(rootElement);
root.render(
<QueryClientProvider client={queryClient}>
<App />
<QueryLoader />
</QueryClientProvider>,
);
此时,一旦全局查询中,有查询被刷新,将会全局展示加载动画指示器,让用户知道数据正在刷新,但是也不影响当前用户的使用。
基于查询过滤器获取isFetching
数据
useIsFetching
同样支持传入查询过滤器,如果你不清楚查询过滤器,你可以查看这篇文章👉🏻react-query手把手教程⑧-查询过滤器。
还是以github为例,如果你需要在详情页,针对其中所有的查询展示是否加载的动画,那么你只需要下面例子中的RepoLoader
组件即可。
import { Spin, Space } from 'antd';
const RepoLoader = ({owner, repo}) => {
const isFetching = useIsFetching(["repo", owner, repo]);
if (isFetching) {
return <Spin />
}
return null;
}
// ①
const repoQuery = useQuery(["repo", owner, repo]);
const issuesQuery = useQuery(["repo", owner, repo, "issues"]);
const pullRequestsQuery = useQuery(["repo", owner, repo, "pulls"]);
// ②
const userQuery = useQuery(["user", username]);
const userReposQuery = useQuery(["user", username, "repos"]);
const issuesQuery = useQuery(["issues", owner, repo]);
在上面的例子中,①里所有的查询,如果有获取数据的场景下,都会展示RepoLoader
。但是②中左右的查询,都不会展示。
这样就能让开发者非常方便地为用户展示,当前数据正在后台加载。
阶段性总结
目前该系列加本文已经有十篇,其中需要认真了解的概念其实有以下几点:
useQuery
常用的属性,比如:isLoading
、isFetching
、data
等- 缓存数据的新旧程度标记,比如:过期(
stale
)等;以及数据在陈旧状态下,什么时机会自动重新获取数据。 - 当前查询的状态,比如:活跃(
active
)、不活跃(inactive
) - 当前查询获取数据的状态,比如获取中(
fetching
)、已暂停(paused
)、请求挂起(idle
) - 合理的去设置查询键(
queryKey
),方便后续查询过滤器的使用 - 批量对查询进行:获取加载状态
useIsFetching
、取消请求cancelQueries
、刷新请求(queryClient.refetchQueries
及queryClient.invalidateQueries
)
开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 17 天,点击查看活动详情