禁用/暂停查询

如果您希望禁用查询,使其不自动运行,可以使用enabled = false选项。该选项还可以接受一个返回布尔值的回调。

enabled设置为false时:

  • 如果查询已有缓存数据,查询将初始化为 status === 'success'isSuccess 状态。

  • 如果查询没有缓存数据,查询将初始化为 status === 'pending'fetchStatus === 'idle' 状态。

  • 查询不会在挂载时自动触发。

  • 查询不会在后台自动重新获取数据。

  • 查询会忽略 queryClient.invalidateQueriesrefetchQueries 调用,这些通常会导致查询重新获取数据。

  • 使用 refetch 返回的函数可以手动触发查询,但与 skipToken 一起使用时不起作用。

示例:禁用查询并手动触发

function Todos() {
  const { isLoading, isError, data, error, refetch, isFetching } = useQuery({
    queryKey: ["todos"],
    queryFn: fetchTodoList,
    enabled: false
  });

  return (
    <div>
      <button onClick={() => refetch()}>Fetch Todos</button>

      {data ? (
        <ul>
          {data.map((todo) => (
            <li key={todo.id}>{todo.title}</li>
          ))}
        </ul>
      ) : isError ? (
        <span>Error: {error.message}</span>
      ) : isLoading ? (
        <span>Loading...</span>
      ) : (
        <span>Not ready ...</span>
      )}

      {isFetching && <div>Fetching...</div>}
    </div>
  );
}

永久禁用查询的注意事项:

永久禁用查询会失去 TanStack Query 提供的许多优秀功能(例如后台重新获取数据),并且也不符合声明式编程的风格。这将把你从声明式模式(定义查询何时运行)转变为命令式模式(点击时才开始获取数据)。通常,您可能只想要一个懒查询,以延迟执行初始请求。

懒查询

enabled 选项不仅可以用来永久禁用查询,还可以在稍后启用或禁用查询。一个典型的例子是:在用户输入筛选条件后,才发起查询请求。

function Todos() {
  const [filter, setFilter] = React.useState("");

  const { data } = useQuery({
    queryKey: ["todos", filter],
    queryFn: () => fetchTodos(filter),
    enabled: !!filter // 当 filter 有值时才启用查询
  });

  return (
    <div>
      <FiltersForm onApply={setFilter} />
      {data && <TodosTable data={data} />}
    </div>
  );
}

在这种情况下,查询在用户输入筛选条件后才会执行。

isLoading(以前是 isInitialLoading

懒查询的状态通常会是 'pending',因为 'pending' 表示没有数据。这意味着,如果查询没有启用,则 isLoading 不会自动显示加载动画。

如果您使用禁用或懒查询,可以使用 isLoading 标志来显示加载状态。isLoading 是通过以下方式计算得出的:

isLoading = isPending && isFetching

isLoading 仅在查询第一次获取数据时为 true

使用 skipToken 实现类型安全的禁用查询

如果您使用 TypeScript,可以使用 skipToken 来禁用查询。这非常适合在条件满足时禁用查询,同时仍然保持查询的类型安全。

注意: refetch 不适用于与 skipToken 一起使用。除这一点外,skipTokenenabled: false 的行为相同。

示例:使用 skipToken 禁用查询

import { skipToken, useQuery } from '@tanstack/react-query'

function Todos() {
  const [filter, setFilter] = React.useState<string | undefined>()

  const { data } = useQuery({
    queryKey: ['todos', filter],
    queryFn: filter ? () => fetchTodos(filter) : skipToken,
  })

  return (
    <div>
      <FiltersForm onApply={setFilter} />
      {data && <TodosTable data={data} />}
    </div>
  )
}

在这个例子中,skipToken 用于在 filterundefined 时禁用查询。如果 filter 有值,查询将会执行。

通过这些方式,您可以灵活地禁用、暂停查询,并实现懒查询和类型安全的禁用查询。

最后更新于

这有帮助吗?