查询是与唯一键绑定的、对异步数据源的声明式依赖。查询可用于任何基于 Promise 的方法(包括 GET 和 POST 方法)从服务器获取数据。如果您的方法会修改服务器上的数据,建议改用变更。
要在组件或自定义钩子中订阅查询,至少需要调用 useQuery 钩子并传入:
import { useQuery } from '@tanstack/react-query'
function App() {
const info = useQuery({ queryKey: ['todos'], queryFn: fetchTodoList })
}
import { useQuery } from '@tanstack/react-query'
function App() {
const info = useQuery({ queryKey: ['todos'], queryFn: fetchTodoList })
}
您提供的唯一键将在内部用于重新获取、缓存和在应用程序中共享查询。
useQuery 返回的查询结果包含模板渲染和数据使用所需的所有信息:
const result = useQuery({ queryKey: ['todos'], queryFn: fetchTodoList })
const result = useQuery({ queryKey: ['todos'], queryFn: fetchTodoList })
result 对象包含几个非常重要的状态,您需要了解这些状态才能高效工作。查询在任意时刻只能处于以下一种状态:
除了这些主要状态外,根据查询状态还可获取更多信息:
对于大多数查询,通常只需检查 isPending 状态,然后是 isError 状态,最后即可假定数据可用并渲染成功状态:
function Todos() {
const { isPending, isError, data, error } = useQuery({
queryKey: ['todos'],
queryFn: fetchTodoList,
})
if (isPending) {
return <span>加载中...</span>
}
if (isError) {
return <span>错误:{error.message}</span>
}
// 此时可以认为 `isSuccess === true`
return (
<ul>
{data.map((todo) => (
<li key={todo.id}>{todo.title}</li>
))}
</ul>
)
}
function Todos() {
const { isPending, isError, data, error } = useQuery({
queryKey: ['todos'],
queryFn: fetchTodoList,
})
if (isPending) {
return <span>加载中...</span>
}
if (isError) {
return <span>错误:{error.message}</span>
}
// 此时可以认为 `isSuccess === true`
return (
<ul>
{data.map((todo) => (
<li key={todo.id}>{todo.title}</li>
))}
</ul>
)
}
如果不喜欢使用布尔值,也可以始终使用 status 状态:
function Todos() {
const { status, data, error } = useQuery({
queryKey: ['todos'],
queryFn: fetchTodoList,
})
if (status === 'pending') {
return <span>加载中...</span>
}
if (status === 'error') {
return <span>错误:{error.message}</span>
}
// 同样 status === 'success',但 "else" 逻辑也适用
return (
<ul>
{data.map((todo) => (
<li key={todo.id}>{todo.title}</li>
))}
</ul>
)
}
function Todos() {
const { status, data, error } = useQuery({
queryKey: ['todos'],
queryFn: fetchTodoList,
})
if (status === 'pending') {
return <span>加载中...</span>
}
if (status === 'error') {
return <span>错误:{error.message}</span>
}
// 同样 status === 'success',但 "else" 逻辑也适用
return (
<ul>
{data.map((todo) => (
<li key={todo.id}>{todo.title}</li>
))}
</ul>
)
}
如果在访问 data 之前检查了 pending 和 error,TypeScript 也会正确缩小 data 的类型范围。
除了 status 字段外,您还会获得一个额外的 fetchStatus 属性,其可选值包括:
后台重新获取和"过时但重新验证"逻辑使得 status 和 fetchStatus 的所有组合都可能出现。例如:
因此请记住,查询可能处于 pending 状态但并未实际获取数据。经验法则:
如需了解执行状态检查的替代方法,请参阅社区资源。