在react-query中使用(isLoading或isFetching)的原因

pvp*_*p11 10 reactjs react-query

我是一个使用react的用户。我在使用react-query时没有很好地使用isloading函数。在ui方面,我认为正在加载用于向用户显示加载屏幕。我认为我不必显示加载,因为数据获取速度很快。

但突然,我想到了这个想法。

如果你把 props 交给子组件,在数据通过 undefined 并获取到数据后,你经常会渲染获取的数据,所以我认为这可能是因为优化渲染的原因,还是有其他原因?

Adr*_*tti 10

我认为你的问题应该得到更详细的答案,因为isFetching它经常被忽视。

正在加载

正如您发现的那样,查询的获取速度足够快,您可能会觉得不需要检查isLoading. 在许多示例中,您会看到类似这样的内容:

  const { data, isLoading } = useQuery(...);

  if (isLoading)
    return <div>Loading...</div>;

  return <DataTable data={data} />;
Run Code Online (Sandbox Code Playgroud)

当第一次获取数据时 ( UseQueryResult.status === "loading"),您会显示某种加载指示器,当数据可用时,您可以随意使用它。

延迟加载指示器

如果查询加载速度很快,那么您将短暂地看到“正在加载...”(或旋转窗口),这不是一个好的用户界面。对于非常短的延迟,最好什么也不显示:您可以使用动画来实现(或设置计时器以使微调器可见),只要将其嵌入到组件中,这并不重要<LoadingIndicator />。我发现 100/150 毫秒的延迟是一个很好的折衷方案(对我来说)。如果您有兴趣,可以通过研究来确定最合适的值。

错误

您可能还想处理错误,为此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} />;
Run Code Online (Sandbox Code Playgroud)

请注意我们如何引入refresh(),当我们调用它时,我们将导致它isFetching成为true(初始获取不会发生)。

正在获取

正如我们所看到的,isFetchingtrue当我们已经有了一个值(或尝试第一次获取)并且我们再次获取相同的数据时。当我们手动触发刷新时,以及当react-query重新加载缓存数据时(在本例中),都是如此status === "success"

这在少数情况下非常重要:

  • 我们可能不想在刷新表格时显示加载指示器。
  • isRefresh是时truedata !== undefined我们可能只想简单地禁用编辑(如果支持)而不显示任何加载指示器(或使用不同的更微妙的指示器)。

我们可能还想使用微妙的视觉线索(例如使文本变暗)显示陈旧数据,如果没有任何变化,那么当新数据可用时,我们将有最小的闪烁和布局变化。也可以看看isPreviousData

重复利用

正如您所看到的,您可能会在一个简单的查询周围有很多样板代码。我喜欢做的是构建一个可重用的组件:

const query = useQuery(...);

return (
  <Query query={query}>
    ({ data }) => <DataTable data={data} />
  </Query>
);
Run Code Online (Sandbox Code Playgroud)

无障碍

不要忘记包含aria-livearia-busy属性,外部容器(数据和加载/错误指示器的父容器)可以定义如下:

<section aria-live="polite" aria-busy={isLoading || isFetching}>
Run Code Online (Sandbox Code Playgroud)

确切的实现取决于您的具体情况,但不要忘记为加载指示器也包含 ARIA 属性(特别是在使用动画/图标时):

<div role="alert" aria-live="polite" aria-label="Loading" />
Run Code Online (Sandbox Code Playgroud)

对于您可能包含的错误横幅(在这种情况下,角色暗示的role="alert"默认值是适当的)。aria-live="assertive""alert"


iha*_*ant 0

我认为你的一些观点击中了要害。

在一段时间内,您的数据未定义,这意味着您的某些代码可能会损坏。

一个非常简单的例子

const MyComponent = () => {
  const { data, loading } = useQuery(..)

  if (loading) return <LoadingComponent />

  return (<table> { data.map((item) => <tr>{item.name}</tr>)} </table>)
}
Run Code Online (Sandbox Code Playgroud)

如果 data 未定义,则 data.map 将中断。但是,您指出您可以检查数据是否存在。

if (!data) return <LoadingComponent/>

但!如果您的查询出错,那么数据将是未定义的,并且您将永远陷入加载状态,而实际上您应该抛出错误消息。

所以你也可以利用 error 属性来解决这个问题

  const { data, error } = useQuery(..)

  if !(data || error) return <LoadingComponent />
Run Code Online (Sandbox Code Playgroud)

现在,您对加载没有太多用处,除非您想让用户知道您的数据正在后台更新(如果您已经缓存了数据)。

例如,假设您已经调用了查询,并且reactquery立即使用缓存填充数据,但它会进行后台检查以确保缓存的数据是最新的,然后您可以使用loading属性来显示一个小旋转器您的数据正在同步!