禁用/暂停查询
如果您希望禁用查询,使其不自动运行,可以使用enabled = false
选项。该选项还可以接受一个返回布尔值的回调。
当enabled
设置为false
时:
如果查询已有缓存数据,查询将初始化为
status === 'success'
或isSuccess
状态。如果查询没有缓存数据,查询将初始化为
status === 'pending'
和fetchStatus === 'idle'
状态。查询不会在挂载时自动触发。
查询不会在后台自动重新获取数据。
查询会忽略
queryClient.invalidateQueries
和refetchQueries
调用,这些通常会导致查询重新获取数据。使用
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
实现类型安全的禁用查询
skipToken
实现类型安全的禁用查询如果您使用 TypeScript,可以使用 skipToken
来禁用查询。这非常适合在条件满足时禁用查询,同时仍然保持查询的类型安全。
注意: refetch
不适用于与 skipToken
一起使用。除这一点外,skipToken
与 enabled: 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
用于在 filter
为 undefined
时禁用查询。如果 filter
有值,查询将会执行。
通过这些方式,您可以灵活地禁用、暂停查询,并实现懒查询和类型安全的禁用查询。
最后更新于
这有帮助吗?