Skip to main content

Queries


Query Basics

查询(Query)是对异步数据源的声明性依赖,它与一个唯一的键(unique key)相关联。可以使用查询与任何基于 Promise 的方法(包括 GET 和 POST 方法)一起,从服务器获取数据。如果你的方法在服务器上修改数据,我们建议使用 Mutations(变更)。

要在组件或自定义钩子中订阅查询,可以调用 useQuery 钩子,至少需要提供以下参数:

  • 查询的唯一键(key)
  • 一个返回 Promise 的函数,该函数可能:
    • 解析数据,或者
    • 抛出错误
import { useQuery } from '@tanstack/react-query';

function App() {
const info = useQuery({ queryKey: ['todos'], queryFn: fetchTodoList })
}

你提供的唯一键(key)在内部用于查询的重新获取(refetching)、缓存(caching)和在应用程序中共享查询(sharing)。

useQuery 返回的查询结果对象包含了关于查询的所有信息,你可以根据这些信息进行模板化和其他数据使用方式:

const result = useQuery({ queryKey: ['todos'], queryFn: fetchTodoList })

result结果对象包含了一些非常重要的状态,你需要了解这些状态以提高工作效率。查询在任何给定的时刻只能处于以下状态之一:

  • isLoadingstatus === 'loading' - 查询尚未有数据
  • isErrorstatus === 'error' - 查询遇到了错误
  • isSuccess 或 status === 'success' - 查询成功并且数据可用 除了这些主要的状态之外,根据查询的状态还可以获取更多的信息:

error - 如果查询处于 isError 状态,可以通过 error 属性获取错误信息。 data - 如果查询处于 isSuccess 状态,可以通过 data 属性获取数据。 对于大多数查询来说,通常只需要检查 isLoading 状态,然后检查 isError 状态,最后可以假设数据可用并渲染成功的状态:

function Todos() {
const { isLoading, isError, data, error } = useQuery({
queryKey: ['todos'],
queryFn: fetchTodoList,
})

if (isLoading) {
return <span>Loading...</span>
}

if (isError) {
return <span>Error: {error.message}</span>
}

// We can assume by this point that `isSuccess === true`
return (
<ul>
{data.map((todo) => (
<li key={todo.id}>{todo.title}</li>
))}
</ul>
)
}

如果布尔值不符合你的需求,也可以使用 status 状态: if (status === 'loading'),if (status === 'error')

如果你在访问它之前检查了加载和错误,TypeScript也会正确地缩小数据的类型。

FetchStatus

除了状态字段 status,你还将获得一个额外的 fetchStatus 属性,它具有以下选项:

fetchStatus === 'fetching' - 查询正在获取数据。 fetchStatus === 'paused' - 查询想要获取数据,但是被暂停了。在 Network Mode 指南中可以了解更多信息。 fetchStatus === 'idle' - 查询当前没有任何操作。

为什么有两个不同的状态? 后台重新获取和过期-同时重新验证(stale-while-revalidate)的逻辑使得 status 和 fetchStatus 可能出现各种组合。例如:

  • 成功状态的查询通常会处于 idle 的 fetchStatus,但如果正在进行后台重新获取,则可能处于 fetching 状态。
  • 当查询挂载且没有数据时,通常会处于 loading 状态和 fetching 的 fetchStatus,但如果没有网络连接,则可能被paused

因此,请记住,查询可能处于 loading 状态,但实际上并未获取数据。作为一个经验法则:

status 提供关于 data 的信息:我们是否有数据? fetchStatus 提供关于 queryFn 的信息:它是否正在运行?