译零 TransZero · TanStack Query 中文文档
主站

查询

更新于 2026-11-02 Solid 查看英文原文 ↗

查询基础

查询是对异步数据源的一种声明式依赖,它与一个唯一键相关联。查询可用于任何基于 Promise 的方法(包括 GET 和 POST 方法)来从服务器拉取数据。如果你的方法会修改服务器上的数据,我们建议改用修改。

要在组件中订阅一个查询,请调用 useQuery 函数,并至少传入以下参数: //: # 'SubscribeDescription'

  • 该查询的唯一键
  • 一个返回 Promise 的函数,该 Promise:
    • 成功解析出数据,或
    • 抛出错误
TypeScript
1import { useQuery } from '@tanstack/solid-query'2 3function App() {4  const todosQuery = useQuery(() => ({5    queryKey: ['todos'],6    queryFn: fetchTodoList,7  }))8}

你提供的唯一键会在内部用于重新拉取、缓存以及在整个应用中共享该查询。

useQuery 返回的查询结果包含了你在模板渲染及数据其他使用场景中所需的所有查询信息:

TypeScript
1const todosQuery = useQuery(() => ({2  queryKey: ['todos'],3  queryFn: fetchTodoList,4}))

result 对象包含若干关键状态,你需要了解这些状态才能高效使用。在任意时刻,查询只能处于以下状态之一:

  • isPending 或 status === 'pending' — 查询尚无数据
  • isError 或 status === 'error' — 查询发生错误
  • isSuccess 或 status === 'success' — 查询成功,数据已就绪

除上述主要状态外,还可根据查询当前所处状态获取更多信息:

  • error — 若查询处于 isError 状态,则可通过 error 属性获取错误对象。
  • data — 若查询处于 isSuccess 状态,则可通过 data 属性获取数据。
  • isFetching — 在任意状态下,只要查询正在拉取数据(包括后台重新拉取),isFetching 值即为 true。

对于大多数查询,通常只需依次检查 isPending 状态、再检查 isError 状态,最后默认数据已就绪并渲染成功状态即可:

TypeScript
1import { Switch, Match, For } from 'solid-js'2 3function Todos() {4  const todosQuery = useQuery(() => ({5    queryKey: ['todos'],6    queryFn: fetchTodoList,7  }))8 9  return (10    <Switch>11      <Match when={todosQuery.isPending}>12        <span>Loading...</span>13      </Match>14      <Match when={todosQuery.isError}>15        <span>Error: {todosQuery.error.message}</span>16      </Match>17      <Match when={todosQuery.isSuccess}>18        <ul>19          <For each={todosQuery.data}>{(todo) => <li>{todo.title}</li>}</For>20        </ul>21      </Match>22    </Switch>23  )24}

若你不习惯使用布尔值判断,也可直接使用 status 状态:

TypeScript
1import { Switch, Match, For } from 'solid-js'2 3function Todos() {4  const todosQuery = useQuery(() => ({5    queryKey: ['todos'],6    queryFn: fetchTodoList,7  }))8 9  return (10    <Switch>11      <Match when={todosQuery.status === 'pending'}>12        <span>Loading...</span>13      </Match>14      <Match when={todosQuery.status === 'error'}>15        <span>Error: {todosQuery.error.message}</span>16      </Match>17      <Match when={todosQuery.status === 'success'}>18        <ul>19          <For each={todosQuery.data}>{(todo) => <li>{todo.title}</li>}</For>20        </ul>21      </Match>22    </Switch>23  )24}

若你在访问 data 前已检查过 pending 和 error,TypeScript 也会正确地收窄 data 的类型。

FetchStatus

除 status 字段外,你还会获得一个额外的 fetchStatus 属性,其取值如下:

  • fetchStatus === 'fetching' — 查询当前正在拉取数据。
  • fetchStatus === 'paused' — 查询本应拉取数据,但已被暂停。更多细节请参阅网络模式指南。
  • fetchStatus === 'idle' — 查询当前未执行任何操作。

为何需要两种不同状态?

后台重新拉取与“过期时验证”(stale-while-revalidate)逻辑使得 status 和 fetchStatus 的所有组合均可能发生。例如:

  • 处于 success 状态的查询通常对应 idle fetchStatus,但如果此时正进行后台重新拉取,则也可能为 fetching。
  • 一个挂载时无数据的查询通常处于 pending 状态和 fetching fetchStatus,但如果当前无网络连接,则可能为 paused。

因此请注意:查询处于 pending 状态并不代表它正在拉取数据。经验法则是:

  • status 表示 data 的情况:我们是否有数据?
  • fetchStatus 表示 queryFn 的情况:拉取操作是否正在运行?

本页为 TanStack Query 文档(Solid 版)的非官方中文翻译,原文由上游团队维护,遵循 MIT 许可。 译文如有偏差,以英文原文为准。

译自上游 59d11de