返回项目目录
开发工具精选项目

TanStack Query

面向 Web 应用的异步服务端状态管理工具,统一处理请求缓存、同步、失效、Mutation 和后台更新。

主要语言TypeScript
开源许可MIT
项目类型开发工具
维护状态活跃维护
OVERVIEW

项目概述

TanStack Query(原 React Query)不绑定 REST、GraphQL 或特定请求库。它围绕 Query Key 管理远程数据生命周期,并为 React、Vue、Solid、Svelte、Preact、Lit 等框架提供适配器。

TanStack Query 是采用 MIT 许可证的异步服务端状态管理库,原名 React Query。它把请求得到的数据视为具有新鲜度、缓存、重试、失效和同步生命周期的 Server State,而不是让开发者手动把 Loading、Error、Data 和时间戳塞进全局 Store。核心 Query Cache 与框架无关,官方为 React、Preact、Vue、Solid、Svelte、Lit 和实验性 Angular 适配器提供 Hooks 或响应式 API;请求函数本身可以使用 fetch、Axios、GraphQL Client 或任意返回 Promise 的实现。

React 版本5.101.4
原名称React Query
管理对象异步 Server State
FEATURES

主要特点

TanStack Query 把远程数据的获取、缓存、刷新和写入协调成可观察的状态模型。

01

协议无关的 Query Function

只要返回 Promise,就可以接入 fetch、Axios、GraphQL、RPC、IndexedDB 或其他异步数据源。

02

Query Key 缓存模型

序列化 Query Key 标识数据身份,参数成为 Key 的一部分后,缓存、去重、失效和预取都能精确工作。

03

Stale-While-Revalidate

先显示缓存数据,再按 staleTime、挂载、窗口聚焦、网络重连或轮询策略在后台重新验证。

04

请求去重与取消

相同 Query 可共享进行中的 Promise,Query Function 还能使用 AbortSignal 在失效或卸载时取消网络工作。

05

Mutation 与失效

useMutation 表达创建、更新和删除操作,成功后可精确 invalidateQueries、setQueryData 或预取相关数据。

06

乐观更新

onMutate 可暂停相关查询、保存旧缓存并提前写入界面,失败时回滚,完成后再与服务端结果同步。

07

分页与无限查询

useQuery 支持分页 Key 与保留上一页数据,useInfiniteQuery 管理 Cursor、页面参数和增量加载。

08

并行与依赖查询

多个 Query 可并行执行,enabled 和 useQueries 能表达依赖条件、动态查询集合和复杂数据组合。

09

结构共享与渲染优化

JSON 兼容数据默认进行 Structural Sharing,并只跟踪组件实际读取的结果属性,减少无关重渲染。

10

SSR、Hydration 与 Streaming

可在服务端 Prefetch 后 Dehydrate Cache,再通过 HydrationBoundary 交给客户端,支持 Next.js 等框架。

11

离线与持久化

Network Mode、Persist Query Client 和 Storage Persister 可支持离线读取、暂停 Mutation 与缓存恢复。

12

Devtools 与 ESLint

官方 Devtools 展示 Query、Observer 和缓存状态,ESLint Plugin 则检查不稳定依赖和对象 Rest 等常见问题。

USE CASES

适用场景

当多个页面共享远程数据、需要后台刷新或 Mutation 后保持一致时,它能显著减少手写状态代码。

SaaS 与管理后台

表格、详情、筛选、编辑和批量操作共享服务端数据,Mutation 后可按业务边界精确失效缓存。

搜索与筛选页面

把关键词、分页和筛选条件放入 Query Key,自动保留各组合缓存并取消过期请求。

无限信息流

useInfiniteQuery 管理 Cursor 与页面集合,可结合虚拟列表实现 Feed、日志和活动记录。

实时与定时刷新界面

轮询、窗口聚焦重取和手动 Cache Update 可用于监控、订单状态和协作数据;实时推送也能写入 Query Cache。

SSR 和全栈 React

路由 Loader 或 Server Component 可以 Prefetch,再通过 Dehydrate/Hydrate 缩短客户端数据瀑布。

多框架产品

共享 Query Core 与业务 Key 约定,同时在 React、Vue、Svelte、Solid 等应用中使用对应官方适配器。

弱网和离线应用

持久化 Cache、Network Mode 与 Mutation 恢复能力可以为 PWA 和移动 Web 提供更连续的数据体验。

EVALUATION

优点与注意事项

技术选型不仅要看能力,也要理解它带来的团队成本。

主要优点

TanStack Query 擅长的地方

  • 把缓存、新鲜度、重试和后台同步从业务组件中抽离
  • 协议无关,可继续使用现有 REST、GraphQL 或 RPC Client
  • Query Key 为去重、失效、预取和参数化缓存提供统一标识
  • Mutation、乐观更新与精确失效能维护读写后的界面一致性
  • 分页、Infinite Query、Suspense、SSR 和离线场景覆盖完整
  • 结构共享与属性跟踪减少许多不必要的 React 重渲染
  • 官方支持多种前端框架,核心概念可跨技术栈复用
  • Devtools 和成熟文档便于观察缓存状态及排查重复请求

需要注意

采用前应考虑的问题

它不是通用客户端状态库

Modal 开关、表单草稿、主题和本地工作流通常应留在组件状态或专用 Store,不能因为 Query Cache 可写就全部放进去。

默认数据立即过期

staleTime 默认是 0,已缓存数据会被视为 Stale,并可能在挂载、聚焦或重连时后台刷新。应按业务容忍度显式设置。

Query Key 必须完整且稳定

Query Function 使用的分页、筛选、用户或租户参数应进入 Key;遗漏会串缓存,使用不稳定对象则增加维护难度。

失效策略需要业务设计

每次 Mutation 后失效全部 Query 会增加流量和界面抖动,完全手写 Cache 又容易遗漏。应定义资源层级和 Key Factory。

fetch 默认不因 4xx/5xx 抛错

Query Function 必须检查 response.ok 并抛出 Error,否则失败响应可能被当成成功数据进入 Cache。

重试并非所有请求都适用

默认失败 Query 会重试。权限错误、参数错误、昂贵请求和服务端限流应根据错误类型调整 retry 与 backoff。

乐观更新必须准备回滚

并发 Mutation、服务端重新排序和权限拒绝会让简单追加失效,需要保存旧值、取消 Query 并在失败后恢复。

SSR 需要隔离 QueryClient

服务端应按请求创建 Cache,避免不同用户数据泄漏;序列化 Hydrated State 时还必须正确转义以防 XSS。

错误的 Prefetch 仍会形成瀑布

把 useQuery 放在深层 Client Component 才开始请求会延迟内容。应结合路由 Loader、Prefetch 和并行请求规划数据边界。

缓存会占用内存

大量高基数 Key、无限页面或大响应需要合理 gcTime、maxPages 和清理策略,服务端尤其不能无界保留。

适配器版本不完全一致

React、Vue、Solid 和 Svelte 包的版本线与 API 发布节奏可能不同,跨框架文档和示例不能机械复制。

QUICK START

快速开始

下面以 React 适配器为例,配置 QueryClient、查询项目、执行新增 Mutation,并加入分页和 SSR Hydration。

1安装 React 适配器与 Devtools
bash
npm install @tanstack/react-query
npm install --save-dev @tanstack/react-query-devtools
2创建并提供 QueryClient
tsx
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { ReactQueryDevtools } from "@tanstack/react-query-devtools";

const queryClient = new QueryClient({
  defaultOptions: {
    queries: {
      staleTime: 60_000,
      retry: 2,
    },
  },
});

export function Providers({ children }: { children: React.ReactNode }) {
  return (
    <QueryClientProvider client={queryClient}>
      {children}
      <ReactQueryDevtools initialIsOpen={false} />
    </QueryClientProvider>
  );
}
3定义可取消的 Query Function
typescript
export type Project = {
  id: string;
  name: string;
  homepage: string;
};

export async function getProjects(signal?: AbortSignal): Promise<Project[]> {
  const response = await fetch("/api/projects", { signal });

  if (!response.ok) {
    throw new Error(`加载失败:${response.status}`);
  }

  return response.json();
}
4读取项目列表
tsx
import { useQuery } from "@tanstack/react-query";
import { getProjects } from "./api";

export function ProjectList() {
  const projectsQuery = useQuery({
    queryKey: ["projects"],
    queryFn: ({ signal }) => getProjects(signal),
    staleTime: 2 * 60 * 1000,
  });

  if (projectsQuery.isPending) return <p>正在加载…</p>;
  if (projectsQuery.isError) {
    return <p role="alert">{projectsQuery.error.message}</p>;
  }

  return (
    <ul>
      {projectsQuery.data.map((project) => (
        <li key={project.id}>{project.name}</li>
      ))}
    </ul>
  );
}
5执行 Mutation 并失效缓存
tsx
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { createProject } from "./api";

export function AddProjectButton() {
  const queryClient = useQueryClient();
  const createMutation = useMutation({
    mutationFn: createProject,
    onSuccess: () =>
      queryClient.invalidateQueries({
        queryKey: ["projects"],
      }),
  });

  return (
    <button
      disabled={createMutation.isPending}
      onClick={() => createMutation.mutate({ name: "New project" })}
    >
      {createMutation.isPending ? "正在添加…" : "添加项目"}
    </button>
  );
}
6加入可回滚的乐观更新
typescript
const createMutation = useMutation({
  mutationFn: createProject,
  onMutate: async (draft) => {
    await queryClient.cancelQueries({ queryKey: ["projects"] });
    const previous = queryClient.getQueryData<Project[]>(["projects"]);

    queryClient.setQueryData<Project[]>(["projects"], (current = []) => [
      ...current,
      { id: "optimistic", ...draft },
    ]);

    return { previous };
  },
  onError: (_error, _draft, context) => {
    queryClient.setQueryData(["projects"], context?.previous);
  },
  onSettled: () => {
    queryClient.invalidateQueries({ queryKey: ["projects"] });
  },
});
7实现平滑分页
tsx
import {
  keepPreviousData,
  useQuery,
} from "@tanstack/react-query";

export function ProjectPage({ page }: { page: number }) {
  const query = useQuery({
    queryKey: ["projects", { page }],
    queryFn: ({ signal }) => getProjectPage(page, signal),
    placeholderData: keepPreviousData,
  });

  return (
    <>
      <ProjectGrid projects={query.data?.items ?? []} />
      {query.isFetching ? <span>正在更新…</span> : null}
    </>
  );
}
8服务端预取并 Hydrate
tsx
import {
  dehydrate,
  HydrationBoundary,
  QueryClient,
} from "@tanstack/react-query";

export default async function ProjectsPage() {
  const queryClient = new QueryClient();

  await queryClient.prefetchQuery({
    queryKey: ["projects"],
    queryFn: () => getProjects(),
  });

  return (
    <HydrationBoundary state={dehydrate(queryClient)}>
      <ProjectList />
    </HydrationBoundary>
  );
}
9执行类型检查与构建
bash
npm run dev

# 发布前执行项目自己的检查
npm run typecheck
npm run build

下一步:先设计稳定的 Query Key,再为每类数据明确 staleTime、错误策略和失效边界。不要把所有客户端 UI 状态放进 Query Cache,也不要默认接受每次聚焦窗口就重新请求的行为。

ALTERNATIVES

类似项目

这些站内框架都有官方 TanStack Query 适配器或常见集成;SWR、Apollo Client 和 RTK Query 代表其他服务端状态方案。

COMPARISON

TanStack Query vs SWR

TanStack Query 与 SWR 都以 Stale-While-Revalidate 改善 React 数据获取,但 TanStack Query 提供更完整的 Query 生命周期、Mutation、分页、失效和多框架能力。

比较维度TanStack QuerySWR
核心抽象QueryClient、Query Cache、Observer 与 Query Key以 Key 和 Fetcher 为中心的轻量 React Hook
框架范围React、Vue、Solid、Svelte、Preact、Lit 等主要面向 React
MutationuseMutation、生命周期、失效和乐观更新通过 mutate、useSWRMutation 与 Cache 更新实现
分页与无限加载useQuery 分页与 useInfiniteQuery 专用模型useSWRInfinite 管理页面 Key 和集合
默认策略数据默认 Stale、失败重试三次、非活跃 Cache 五分钟回收自动聚焦重验证与轻量缓存默认值
渲染优化结构共享、属性跟踪与 select依赖比较和 Hook 订阅优化
Devtools官方 Query Cache Devtools 与 ESLint Plugin生态工具较轻量
学习与配置概念和选项更多,适合复杂数据流API 较小,简单请求更快上手
更适合复杂读写、分页、离线、SSR 和多框架产品React 中轻量读取、简单刷新和较少 Mutation
如何选择

如果应用以少量读取请求为主,希望用极简 Hook 获得缓存与重新验证,SWR 往往足够;如果存在复杂 Mutation、乐观更新、Infinite Query、精细失效、离线或跨框架需求,TanStack Query 的完整状态模型更合适。无论选择哪一个,都应先定义服务端数据的新鲜度、错误策略和 Query Key。

VERIFICATION

资料核验

版本、维护信息与本页采用的官方资料来源。

最后核验2026 年 7 月 29 日
核验版本@tanstack/react-query 5.101.4
内容维护Docs100 编辑整理
项目维护状态活跃维护

本页依据 TanStack Query 官方 React Quick Start、Important Defaults、Caching、Mutation、Render Optimizations、SSR 与框架支持文档,以及 npm 和官方源码仓库整理。版本指 React 适配器;Vue、Svelte、Solid 等适配器可能采用不同版本线。

维护状态核验2026 年 7 月 26 日 · 最近可见代码活动:2026 年 7 月 29 日

官方仓库未归档,核验时最近可见的代码活动日期为 2026 年 7 月 29 日。该状态表示项目近期仍有公开维护活动,不代表固定发布频率或长期支持承诺。

查看官方仓库