禁用/暂停查询 Disabling/Pausing Queries
如果要禁用自动运行的查询,则可以使用enabled = false
选项。
当 enabled
是 false
时:
- 如果查询已缓存了数据
- 查询将以
status === 'success'
或isSuccess
的状态进行初始化
- 查询将以
- 如果查询没有缓存的数据
- 查询将以
status === 'loading'
和fetchStatus === 'idle'
的状态进行初始化
- 查询将以
- 该查询不会在挂载时自动获取数据
- 该查询不会自动在后台重新获取数据
- 该查询将忽略查询客户端的
invalidateQueries
和refetchQueries
调用,这些调用通常会导致查询重新获取数据 - 从
useQuery
返回的refetch
可用于手动触发查询以进行数据获取
function Todos() {
const { isInitialLoading, 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>
) : isInitialLoading ? (
<span>Loading...</span>
) : (
<span>Not ready ...</span>
)}
<div>{isFetching ? "Fetching..." : null}</div>
</div>
);
}
永久性地禁用一个查询会使你失去 TanStack Query 所提供的许多优秀的功能(如后台的重新请求),而且这也不是一种自然的方式。
它把你从声明性的方法(定义查询应该何时运行的依赖关系)带入了命令性的模式(每当我点击这里时就会获取)。
它也不可能传递参数给refetch
。
很多时候,你想要的可能只是一个惰性查询:
惰性查询
enabled
选项不仅可以用来永久禁用一个查询,还可以让你在稍晚的时候启用或者禁用它。
一个很好的例子是一个带过滤器的表单,你只想在用户输入了一个用于过滤的关键词后才发起第一次请求:
function Todos() {
const [filter, setFilter] = React.useState("");
const { data } = useQuery({
queryKey: ["todos", filter],
queryFn: () => fetchTodos(filter),
// ⬇️ 只要filter为空则禁用
enabled: !!filter,
});
return (
<div>
{/* 🚀 过滤的关键词设置后将启用并执行查询 */}
<FiltersForm onApply={setFilter} />
{data && <TodosTable data={{ data }} />}
</div>
);
}
isInitialLoading
惰性查询一开始就会处于status: 'loading'
的状态,因为它的真实加载时机不确定且它的确暂时没有数据。
由于我们目前没有获取任何数据(因为enabled已被禁用),这意味着你很有可能没法使用这个字段来显示一个“正在加载”的样式。
如果你禁用了自动运行的查询或者使用了惰性查询,你可以选择使用isInitialLoading
字段。
这是一个派生的标志,是由部分内容计算出来的:isLoading && isFetching
所以只有当查询正在进行第一次获取时,它才会为真。