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

查询

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

初次接触 Lit Query?请先阅读 安装 和 快速上手,再将查询控制器集成到你的元素中。

查询基础

查询是对一个异步数据源的声明式依赖,该依赖与一个唯一查询键相关联。使用查询来读取服务端状态(server state)。如果某个函数用于创建、更新或删除服务端数据,请改用 修改。

在 Lit 中,使用 createQueryController 订阅查询:

TypeScript
1import { LitElement, html } from 'lit'2import { createQueryController } from '@tanstack/lit-query'3 4class TodosView extends LitElement {5  private readonly todos = createQueryController(this, {6    queryKey: ['todos'],7    queryFn: fetchTodos,8  })9 10  render() {11    const query = this.todos()12 13    if (query.isPending) return html`Loading...`14    if (query.isError) return html`Error: ${query.error.message}`15 16    return html`17      <ul>18        ${query.data.map((todo) => html`<li>${todo.title}</li>`)}19      </ul>20    `21  }22}

该控制器需要:

  • 一个 ReactiveControllerHost,通常为 this,位于 LitElement 内部
  • 一个唯一的 queryKey
  • 一个 queryFn,它返回 Promise,并在出错时抛出异常

返回的访问器暴露当前 QueryObserverResult。你可在 render 中调用它,或直接读取 .current:

TypeScript
1const query = this.todos()2const sameQuery = this.todos.current

查询状态

查询在任一时刻仅处于一种主要状态:

  • isPending 或 status === 'pending':尚无可用数据
  • isError 或 status === 'error':查询失败,且 error 可用
  • isSuccess 或 status === 'success':数据可用

结果还包含 isFetching,它在初始加载或后台重新拉取期间可能为 true。

TypeScript
1render() {2  const query = this.todos()3 4  if (query.status === 'pending') {5    return html`<span>Loading...</span>`6  }7 8  if (query.status === 'error') {9    return html`<span>Error: ${query.error.message}</span>`10  }11 12  return html`<todo-list .items=${query.data}></todo-list>`13}

TypeScript 会在你检查 pending 和 error 后对 query.data 进行类型收窄,然后再读取它。

拉取状态

status 字段描述数据是否可用。fetchStatus 字段描述查询函数当前正在执行的操作:

  • fetchStatus === 'fetching':查询正在进行拉取。
  • fetchStatus === 'paused':查询本应拉取,但拉取已被暂停。
  • fetchStatus === 'idle':查询未进行拉取。

这些状态被有意设计为相互独立。后台重新拉取和“过期时验证”(stale-while-revalidate)行为可能导致如下组合:

  • 一个成功的查询若拥有缓存数据,在后台重新拉取运行期间,可能同时具有 status === 'success' 和 fetchStatus === 'fetching'。
  • 一个尚无数据的查询,若拉取尚不能启动,则可能同时具有 status === 'pending' 和 fetchStatus === 'paused'。

在决定是否渲染数据时,请使用 status;在决定是否显示网络活动指示器时,请使用 fetchStatus 或 isFetching:

TypeScript
1render() {2  const query = this.todos()3 4  if (query.isPending) return html`Loading...`5  if (query.isError) return html`Error: ${query.error.message}`6 7  return html`8    ${query.fetchStatus === 'fetching'9      ? html`<span>Refreshing...</span>`10      : null}11    <todo-list .items=${query.data}></todo-list>12  `13}

响应式查询选项

当查询键或查询函数依赖于宿主(host)状态时,请使用选项 getter:

TypeScript
1class UserTodos extends LitElement {2  static properties = {3    userId: { type: String },4  }5 6  userId = ''7 8  private readonly todos = createQueryController(this, () => ({9    queryKey: ['todos', this.userId],10    queryFn: () => fetchTodos(this.userId),11    enabled: this.userId.length > 0,12  }))13}

查询键用于缓存、重新拉取以及控制器间的数据共享。

重新拉取

访问器包含 refetch:

TypeScript
1html`<button @click=${() => this.todos.refetch()}>Refetch</button>`

如需同时运行多个查询,请参阅 并行查询。

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

译自上游 59d11de