如果您不想让某个查询自动运行,可以使用 enabled = false 选项。enabled 选项也接受一个返回布尔值的回调函数。
当 enabled 为 false 时:
TypeScript 用户可能更喜欢使用 skipToken 作为 enabled = false 的替代方案。
function Todos() {
const { isLoading, isError, data, error, refetch, isFetching } = useQuery(() => {
queryKey: ['todos'],
queryFn: fetchTodoList,
enabled: false,
})
return (
<div>
<button onClick={() => refetch()}>获取待办事项</button>
{data ? (
<>
<ul>
{data.map((todo) => (
<li key={todo.id}>{todo.title}</li>
))}
</ul>
</>
) : isError ? (
<span>错误:{error.message}</span>
) : isLoading ? (
<span>加载中...</span>
) : (
<span>未就绪...</span>
)}
<div>{isFetching ? '正在获取...' : null}</div>
</div>
)
}
function Todos() {
const { isLoading, isError, data, error, refetch, isFetching } = useQuery(() => {
queryKey: ['todos'],
queryFn: fetchTodoList,
enabled: false,
})
return (
<div>
<button onClick={() => refetch()}>获取待办事项</button>
{data ? (
<>
<ul>
{data.map((todo) => (
<li key={todo.id}>{todo.title}</li>
))}
</ul>
</>
) : isError ? (
<span>错误:{error.message}</span>
) : isLoading ? (
<span>加载中...</span>
) : (
<span>未就绪...</span>
)}
<div>{isFetching ? '正在获取...' : null}</div>
</div>
)
}
永久禁用查询会使您无法使用 TanStack Query 提供的许多强大功能(例如后台重新获取),而且这也不是惯用的方法。它将您从声明式方法(定义查询何时应运行的依赖项)带入命令式模式(在我单击此处时获取)。也无法将参数传递给 refetch。通常,您想要的只是一个延迟初始获取的惰性查询:
enabled 选项不仅可以用于永久禁用查询,还可以用于稍后启用/禁用它。一个很好的例子是一个过滤器表单,您只想在用户输入过滤器值后才发出第一个请求:
function Todos() {
const [filter, setFilter] = React.useState('')
const { data } = useQuery(() => {
queryKey: ['todos', filter],
queryFn: () => fetchTodos(filter),
// ⬇️ 只要过滤器为空就禁用
enabled: !!filter,
})
return (
<div>
// 🚀 应用过滤器将启用并执行查询
<FiltersForm onApply={setFilter} />
{data && <TodosTable data={data} />}
</div>
)
}
function Todos() {
const [filter, setFilter] = React.useState('')
const { data } = useQuery(() => {
queryKey: ['todos', filter],
queryFn: () => fetchTodos(filter),
// ⬇️ 只要过滤器为空就禁用
enabled: !!filter,
})
return (
<div>
// 🚀 应用过滤器将启用并执行查询
<FiltersForm onApply={setFilter} />
{data && <TodosTable data={data} />}
</div>
)
}
惰性查询从一开始就处于 status: 'pending' 状态,因为 pending 表示还没有数据。这在技术上是正确的,但是,由于我们当前没有获取任何数据(因为查询未_启用_),这也意味着您可能无法使用此标志来显示加载微调器。
如果您正在使用禁用或惰性查询,则可以改用 isLoading 标志。它是一个派生标志,计算方式如下:
isPending && isFetching
因此,只有当查询首次获取时,它才会为 true。
如果您正在使用 TypeScript,则可以使用 skipToken 来禁用查询。当您想根据条件禁用查询,但仍希望保持查询类型安全时,这很有用。
重要提示:从 useQuery 返回的 refetch 不适用于 skipToken。除此之外,skipToken 的工作方式与 enabled: false 相同。
import { skipToken, useQuery } from '@tanstack/solid-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>
)
}
import { skipToken, useQuery } from '@tanstack/solid-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>
)
}