queries(查询)

查询基础 (Query Basics)

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

要在组件或自定义 Hook 中订阅查询,请调用 useQuery hook,其中至少包含:

  • 一个 查询的唯一键

  • 一个返回 Promise 的函数,该函数:

    • 解析(Resolve)数据,或者
    • 抛出(Throw)错误
TypeScript 复制代码
import { useQuery } from '@tanstack/react-query'

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

你提供的 唯一键 在内部用于在整个应用程序中重新获取、缓存和共享你的查询。

useQuery 返回的查询结果包含了你在模板化或以其他方式使用数据时所需的所有信息:

TypeScript 复制代码
const result = useQuery({ queryKey: ['todos'], queryFn: fetchTodoList })

result 对象包含几个非常重要的状态,你需要了解它们才能高效工作。在任何给定时刻,查询只能处于以下状态之一:

  • isPendingstatus === 'pending' - 查询尚无数据
  • isErrorstatus === 'error' - 查询遇到错误
  • isSuccessstatus === 'success' - 查询成功且数据可用

除了这些主要状态之外,根据查询的状态,还有更多信息可用:

  • error - 如果查询处于 isError 状态,可以通过 error 属性获取错误信息。
  • data - 如果查询处于 isSuccess 状态,可以通过 data 属性获取数据。
  • isFetching - 在任何状态下,如果查询在任何时候正在获取数据(包括后台重新获取),isFetching 将为 true

对于 大多数 查询,通常只需检查 isPending 状态,然后是 isError 状态,最后假设数据可用并渲染成功状态即可:

TypeScript 复制代码
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 状态:

TypeScript 复制代码
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 之前检查了 pendingerror,TypeScript 也会正确地缩小 data 的类型范围。

FetchStatus (获取状态)

除了 status 字段外,你还将获得一个额外的 fetchStatus 属性,其选项如下:

  • fetchStatus === 'fetching' - 查询当前正在获取数据。
  • fetchStatus === 'paused' - 查询想要获取数据,但被暂停了。更多信息请阅读 网络模式 指南。
  • fetchStatus === 'idle' - 查询当前没有进行任何操作。

为什么有两种不同的状态?

后台重新获取(Background refetches)和"过期时重新验证(stale-while-revalidate)"逻辑使得 statusfetchStatus 的所有组合成为可能。例如:

  • 一个处于 success 状态的查询通常 fetchStatusidle,但如果正在进行后台重新获取,它也可能处于 fetching 状态。
  • 一个刚挂载且没有数据的查询通常处于 pending 状态和 fetchingfetchStatus,但如果没有网络连接,它也可能是 paused

所以请记住,查询可能处于 pending 状态,但实际上并没有在获取数据。作为一个经验法则:

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

延伸阅读

关于执行状态检查的另一种方法,请查看 TkDodo 的这篇文章

相关推荐
jacGJ5 小时前
记录学习--文件读写
java·前端·学习
毕设源码-赖学姐5 小时前
【开题答辩全过程】以 基于WEB的实验室开放式管理系统的设计与实现为例,包含答辩的问题和答案
前端
幻云20105 小时前
Python深度学习:从筑基到登仙
前端·javascript·vue.js·人工智能·python
我即将远走丶或许也能高飞7 小时前
vuex 和 pinia 的学习使用
开发语言·前端·javascript
钟离墨笺7 小时前
Go语言--2go基础-->基本数据类型
开发语言·前端·后端·golang
爱吃泡芙的小白白7 小时前
Vue 3 核心原理与实战:从响应式到企业级应用
前端·javascript·vue.js
卓怡学长8 小时前
m115乐购游戏商城系统
java·前端·数据库·spring boot·spring·游戏
老陈聊架构8 小时前
『AI辅助Skill』掌握三大AI设计Skill:前端独立完成产品设计全流程
前端·人工智能·claude·skill
Ulyanov9 小时前
从桌面到云端:构建Web三维战场指挥系统
开发语言·前端·python·tkinter·pyvista·gui开发
cypking9 小时前
二、前端Java后端对比指南
java·开发语言·前端