我认为你的问题值得更详细的回答,因为isFetching
经常被忽视。
正在加载
正如您发现的那样,查询的获取速度足够快,您可能会觉得不需要检查isLoading
。在许多示例中,您会看到类似这样的内容:
const { data, isLoading } = useQuery(...);
if (isLoading)
return <div>Loading...</div>;
return <DataTable data={data} />;
当第一次获取数据时(UseQueryResult.status === "loading"
)你显示一个加载指示器某种形式,当数据可用时,您可以随意使用它。
延迟加载指示器
如果查询加载速度很快,那么您将短暂地看到“正在加载...”(或旋转窗口),这不是一个好的用户界面。对于非常短的延迟,最好什么也不显示:您可以使用动画来实现(或设置计时器以使微调器可见),只要将其嵌入到您的<LoadingIndicator />
成分。我发现 100/150 毫秒的延迟是一个很好的折衷方案(对我来说)。如果您有兴趣,可以通过研究来确定最合适的值。
Errors
您可能还想处理错误,有isError
为此(或者你可以简单地使用status
对于一切)。稍微复杂一点的典型实现如下所示:
const { status, data, error, refresh } = useQuery(...);
if (status === "loading")
return <LoadingIndicator />;
if (status === "error" />
return <Error error={error} onRetry={refresh} />
return <DataTable data={data} onRefresh={refresh} />;
注意我们是如何介绍的refresh()
,当我们调用它时,我们会导致isFetching
to be true
(初始获取不会发生这种情况)。
正在获取
正如我们所看到的,isFetching
is true
当我们已经有一个值(或尝试第一次获取)并且我们再次获取相同的数据时。当我们manually触发刷新,但也会在react-query重新加载缓存数据时触发刷新(在本例中status === "success"
).
这在少数情况下非常重要:
- 我们可能不想在刷新表格时显示加载指示器。
- When
isRefresh
is true
and data !== undefined
我们可能想简单地禁用编辑(如果支持)而不显示任何加载指示器(或使用不同的更微妙的指示器)。
我们可能还想使用微妙的视觉线索(例如使文本变暗)显示陈旧数据,如果没有任何变化,那么当有新数据可用时,我们将有最小的闪烁和布局变化。也可以看看isPreviousData
.
Reuse
正如您所看到的,您可能会在一个简单的查询周围有很多样板代码。我喜欢做的是构建一个可重用的组件:
const query = useQuery(...);
return (
<Query query={query}>
({ data }) => <DataTable data={data} />
</Query>
);
无障碍
不要忘记包括aria-live
and aria-busy
属性,外部容器(数据和加载/错误指示器的父容器)可以这样定义:
<section aria-live="polite" aria-busy={isLoading || isFetching}>
确切的实现取决于您的具体情况,但不要忘记为加载指示器也包含 ARIA 属性(特别是在使用动画/图标时):
<div role="alert" aria-live="polite" aria-label="Loading" />
对于错误banner你可以包括role="alert"
(在这种情况下默认aria-live="assertive"
所暗示的"alert"
角色合适)。