TanStack Query
强大且框架无关的异步状态管理库,为 TypeScript / JavaScript 应用提供高效的数据获取、缓存、同步与更新能力。
TanStack Query(原名 React Query)是专为异步状态管理设计的库,提供智能缓存、自动后台更新、请求去重、分页与无限滚动等能力。支持 React/Vue/Solid/Svelte 四大框架,拥有强大的 DevTools。GitHub 约 5 万 Stars,npm 周下载量超 1200 万次,是现代前端处理服务端状态的事实标准之一。
TanStack Query
强大且框架无关的异步状态管理库,为 TypeScript / JavaScript 应用提供高效的数据获取、缓存、同步与更新能力。
技术简介说明
TanStack Query(原名 React Query)是一个专为异步状态管理设计的库,用于简化服务端状态(Server State)的获取、缓存、同步和更新。它解决了前端开发中最常见的痛点之一——如何高效地与服务端交互并保持客户端状态的一致性。从 React Query 起步,现已演化为完全框架无关的实现,支持 React、Vue、Solid 和 Svelte 四大主流框架。
TanStack Query 的核心理念是将服务端状态与客户端状态分离管理。它提供了开箱即用的缓存机制、自动后台更新、请求去重、并行查询优化、分页与无限滚动等能力,大幅减少了开发者在数据获取层需要编写的样板代码。其类型安全的 API 设计和强大的开发者工具(DevTools)使其成为 2025-2026 年最受欢迎的数据获取解决方案。
截至 2026 年中期,TanStack Query 在 npm 上的周下载量超过 1200 万次,GitHub Stars 约 5 万颗,拥有超过 2790 名贡献者和超过 40 亿次累计下载量。它是现代前端技术栈中处理服务端状态的事实标准之一,与 Zustand 的组合正成为 2026 年 React 生态的新默认技术选型。
基本信息
| 项目 | 内容 |
|---|---|
| 官网 | https://tanstack.com/query/latest |
| GitHub | https://github.com/TanStack/query |
| License | MIT |
| 最新版本 | v5.101.0(React,2026 年 6 月);v6.1.36(Svelte,2026 年 6 月) |
| 创建者 / 维护者 | Tanner Linsley(GitHub) |
| GitHub Stars | ~49,857(2026 年 6 月) |
| npm 周下载量 | ~12M+(@tanstack/react-query 单包约 59M) |
| 框架支持 | React、Vue、Solid、Svelte |
| TypeScript | 原生支持,类型安全 |
| 首次发布 | 2019 年(React Query v1) |
| Bundle Size | ~13kB(gzip,React 适配器) |
快速上手
安装
# npm
npm install @tanstack/react-query
# pnpm
pnpm add @tanstack/react-query
# yarn
yarn add @tanstack/react-query其他框架对应包名:
- Vue:
@tanstack/vue-query - Solid:
@tanstack/solid-query - Svelte:
@tanstack/svelte-query
基础配置
// main.tsx
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { ReactQueryDevtools } from '@tanstack/react-query-devtools'
// 创建 QueryClient 实例
const queryClient = new QueryClient({
defaultOptions: {
queries: {
staleTime: 1000 * 60 * 5, // 5 分钟内数据视为新鲜
retry: 1, // 失败重试 1 次
refetchOnWindowFocus: true // 窗口聚焦时重新获取
}
}
})
function App() {
return (
<QueryClientProvider client={queryClient}>
<YourApp />
<ReactQueryDevtools initialIsOpen={false} />
</QueryClientProvider>
)
}最小示例
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
// 数据获取
function UserList() {
const { data, isLoading, error, refetch } = useQuery({
queryKey: ['users'],
queryFn: async () => {
const response = await fetch('/api/users')
if (!response.ok) throw new Error('Network error')
return response.json()
}
})
if (isLoading) return <div>加载中...</div>
if (error) return <div>错误: {error.message}</div>
return (
<div>
<h1>用户列表</h1>
<button onClick={() => refetch()}>刷新</button>
<ul>
{data.map(user => (
<li key={user.id}>{user.name}</li>
))}
</ul>
</div>
)
}
// 数据变更
function CreateUser() {
const queryClient = useQueryClient()
const mutation = useMutation({
mutationFn: (newUser) => fetch('/api/users', {
method: 'POST',
body: JSON.stringify(newUser)
}),
onSuccess: () => {
// 成功后使缓存失效并重新获取
queryClient.invalidateQueries({ queryKey: ['users'] })
}
})
return (
<form onSubmit={(e) => {
e.preventDefault()
mutation.mutate({ name: '新用户' })
}}>
<button type="submit">创建用户</button>
{mutation.isPending && <span>提交中...</span>}
</form>
)
}核心概念与架构
核心架构设计
TanStack Query 采用分层架构设计,将核心逻辑与框架适配器解耦:
┌─────────────────────────────────────────────┐
│ 框架适配器层(Adapters) │
│ React / Vue / Solid / Svelte │
├─────────────────────────────────────────────┤
│ QueryClient(查询客户端) │
│ 缓存管理、查询调度、失效策略、订阅通知 │
├─────────────────────────────────────────────┤
│ QueryCache(查询缓存) │
│ 存储查询结果、状态追踪、垃圾回收 │
├─────────────────────────────────────────────┤
│ Observer(观察者模式) │
│ 连接 UI 与缓存,驱动重新渲染 │
├─────────────────────────────────────────────┤
│ Core(核心引擎) │
│ Query、Mutation、QueryObserver │
└─────────────────────────────────────────────┘
核心概念
-
Query(查询):代表一个异步数据源,由
queryKey唯一标识。Query 有生命周期状态:pending(加载中)→success(成功)或error(失败)。 -
Mutation(变更):代表创建、更新、删除等写操作。与 Query 不同,Mutation 不会自动执行,需要显式触发。
-
QueryKey(查询键):用于唯一标识和分组查询。支持字符串、数组、对象等形式,数组顺序和对象属性顺序都影响键的唯一性。
-
QueryClient(查询客户端):管理缓存、配置默认选项、提供手动控制缓存的方法(如
invalidateQueries、setQueryData)。 -
Stale Time / GC Time:
staleTime:数据被视为"新鲜"的时间,期间不会触发后台重新获取gcTime(Garbage Collection Time):缓存保留时间,默认 5 分钟
-
QueryObserver(查询观察者):连接 Query 与 React/Vue 组件的桥梁,负责状态变更通知和重新渲染驱动。
核心特性
1. 自动缓存与后台刷新
内置智能缓存机制,自动在后台检查数据新鲜度并更新缓存,用户无需手动管理缓存失效逻辑。
2. 请求去重与并行查询优化
对相同 queryKey 的并发请求自动去重,useQueries 支持并行执行多个独立查询并统一处理状态。
3. 分页与无限滚动
useInfiniteQuery:内置无限滚动支持,配合fetchNextPage/fetchPreviousPage轻松实现分页加载- 游标分页和偏移分页均有内置支持
4. 乐观更新(Optimistic Updates)
v5 大幅简化了乐观更新的实现,通过 onMutate 回调可以在请求完成前立即更新 UI,提供即时的用户反馈。
const mutation = useMutation({
mutationFn: updateTodo,
onMutate: async (newTodo) => {
await queryClient.cancelQueries({ queryKey: ['todos'] })
const previous = queryClient.getQueryData(['todos'])
queryClient.setQueryData(['todos'], old => [...old, newTodo])
return { previous }
},
onError: (err, newTodo, context) => {
queryClient.setQueryData(['todos'], context.previous)
},
onSettled: () => {
queryClient.invalidateQueries({ queryKey: ['todos'] })
}
})5. 一流的 Suspense 支持
v5 提供了原生的 Suspense 集成,useSuspenseQuery 和 useSuspenseQueries 让数据获取与 React 的并发特性完美结合。
6. 共享 Mutation 状态
useMutationState 允许订阅所有 mutation 的状态变化,适用于显示全局加载指示器或通知。
7. 流式查询(streamedQuery)
v5.69.0 新增 streamedQuery,支持流式响应处理(如 ChatGPT 风格的流式输出),是现代 AI 应用的关键能力。
8. 强大的开发者工具
React Query DevTools 提供可视化缓存检查、查询状态监控、mutation 追踪、性能分析等功能,是调试异步逻辑的利器。
9. 离线支持与持久化缓存
通过 persistQueryClient 插件可以将缓存持久化到 localStorage、IndexedDB 或自定义存储,支持离线访问。
10. 框架无关设计
核心逻辑完全独立于 UI 框架,通过适配器模式支持 React、Vue、Solid、Svelte,API 保持一致。
生态图
TanStack Query 是 TanStack 生态系统的一部分:
TanStack 生态
├── TanStack Query —— 异步状态管理 / 数据获取
│ ├── React Query
│ ├── Vue Query
│ ├── Solid Query
│ └── Svelte Query
├── TanStack Router —— 类型安全的路由
├── TanStack Table —— 无头表格组件
├── TanStack Form —— 表单管理
├── TanStack Virtual —— 虚拟滚动
├── TanStack DB —— 响应式客户端存储(新)
└── TanStack Start —— 全栈元框架(基于 Router + Query)
周边工具与插件
| 包名 | 功能 |
|---|---|
@tanstack/react-query-devtools | React 开发者工具 |
@tanstack/query-persist-client-core | 持久化缓存核心 |
@tanstack/query-sync-storage-persister | localStorage 持久化适配器 |
@tanstack/query-async-storage-persister | AsyncStorage(React Native)持久化适配器 |
@tanstack/eslint-plugin-query | ESLint 规则(如 exhaustive-deps) |
@tanstack/query-codemods | 版本迁移代码转换工具 |
适用场景
1. CRUD 应用
管理服务端实体的增删改查,自动处理缓存同步、乐观更新和错误恢复。
2. 分页列表与无限滚动
电商商品列表、社交媒体信息流、数据表格分页等场景,useInfiniteQuery 提供了开箱即用的解决方案。
3. 实时数据仪表盘
结合 refetchInterval 实现定时轮询,或配合 WebSocket 实现实时数据更新,适用于监控仪表盘、股票行情等场景。
4. 表单提交与数据变更
通过 Mutation 处理表单提交,结合乐观更新提供流畅的用户体验,自动处理回滚和错误恢复。
5. 离线优先应用
配合持久化缓存插件,实现离线可用、在线自动同步的 PWA 应用。
6. AI / 流式响应应用
使用 streamedQuery 处理 LLM 的流式输出,实现 ChatGPT 风格的实时对话界面。
7. 微前端 / 模块化应用
在微前端架构中,各模块独立管理自己的数据获取逻辑,通过 queryKey 命名空间避免缓存冲突。
开发与工程化
TypeScript 支持
TanStack Query 从 v4 开始提供完整的 TypeScript 支持,v5 进一步强化了类型推导:
interface User {
id: string
name: string
email: string
}
// 自动推导 data 类型为 User | undefined
const { data } = useQuery({
queryKey: ['users', userId],
queryFn: (): Promise<User> => fetchUser(userId)
})
// data 的类型被精确推导
if (data) {
console.log(data.name) // 类型安全
}ESLint 集成
pnpm add -D @tanstack/eslint-plugin-query推荐规则:
{
"plugins": ["@tanstack/query"],
"rules": {
"@tanstack/query/exhaustive-deps": "error"
}
}测试策略
import { render, screen, waitFor } from '@testing-library/react'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { UserList } from './UserList'
function createWrapper() {
const queryClient = new QueryClient({
defaultOptions: {
queries: { retry: false }
}
})
return function Wrapper({ children }) {
return (
<QueryClientProvider client={queryClient}>
{children}
</QueryClientProvider>
)
}
}
test('显示用户列表', async () => {
render(<UserList />, { wrapper: createWrapper() })
await waitFor(() => {
expect(screen.getByText('用户列表')).toBeInTheDocument()
})
})生产环境配置建议
const queryClient = new QueryClient({
defaultOptions: {
queries: {
staleTime: 1000 * 60 * 5, // 5 分钟新鲜期
gcTime: 1000 * 60 * 30, // 30 分钟缓存保留
retry: 2, // 失败重试 2 次
retryDelay: (attempt) => Math.min(1000 * 2 ** attempt, 30000),
refetchOnWindowFocus: true,
refetchOnReconnect: true,
networkMode: 'online' // 'online' | 'always' | 'offlineFirst'
},
mutations: {
retry: 0 // Mutation 默认不重试
}
}
})性能与安全
性能优化
- 选择性订阅:使用
select选项只订阅需要的数据子集,减少不必要的重渲染 - 查询键粒度控制:合理设计
queryKey,避免过粗导致不相关的更新 - Suspense 边界:配合 React Suspense 实现更精细的加载状态管理
- 结构共享:默认启用结构共享(structural sharing),避免相同数据的重复渲染
- 并行查询:使用
useQueries并行执行多个查询,减少瀑布式请求
安全考量
- 输入验证:
queryKey和queryFn中的参数需要做输入验证,防止注入攻击 - 敏感数据处理:避免将敏感信息(如 token)存入
queryKey,防止泄露到 DevTools - 缓存清理:用户登出时调用
queryClient.clear()清除所有缓存 - XSS 防护:渲染缓存数据时注意转义,避免存储型 XSS
- CSP 兼容:DevTools 在生产环境应禁用或按需加载
npm 供应链安全事件
2026 年 5 月,TanStack 遭遇了 npm 供应链攻击事件,受影响的是 @tanstack/react-router 包,@tanstack/query* 系列包未受影响。团队在 3 天内完成安全审计并发布了修复版本。这一事件提醒开发者在生产环境中使用 lockfile 和依赖审计工具。
技术对比
TanStack Query vs SWR vs RTK Query vs Apollo Client
| 特性 | TanStack Query v5 | SWR v3 | RTK Query | Apollo Client |
|---|---|---|---|---|
| 框架支持 | React / Vue / Solid / Svelte | 仅 React | 仅 React(Redux) | React / Vue(有限) |
| 协议支持 | REST / GraphQL / 任意 | REST / 任意 | REST | GraphQL 原生 |
| Bundle Size | ~13kB | ~3kB | 依赖 Redux(~11kB + Redux) | ~50kB+ |
| 缓存策略 | 智能缓存 + 垃圾回收 | 基于 key 的简单缓存 | 基于 endpoint 的缓存 | 规范化缓存 |
| DevTools | ⭐ 强大 | 基础 | Redux DevTools | Apollo DevTools |
| Suspense | ⭐ 原生支持 | 支持(v2.2+) | 需额外配置 | 支持 |
| 乐观更新 | ⭐ 简化 API | 手动实现 | 内置 | 内置 |
| 分页 / 无限滚动 | ⭐ 原生 | 手动实现 | 手动实现 | 原生 GraphQL 分页 |
| 类型安全 | ⭐ 完整 | 基础 | 良好 | ⭐ 完整 |
| 离线支持 | ⭐ 插件扩展 | 手动实现 | 手动实现 | 有限 |
| 学习曲线 | 中等 | 低 | 高(需学 Redux) | 高(需学 GraphQL) |
| 社区活跃度 | ⭐ 极高 | 高 | 中 | 高 |
| 适合场景 | 通用服务端状态 | 简单数据获取 | Redux 项目 | GraphQL 项目 |
选型建议
- 选 TanStack Query:通用场景首选,框架无关,生态最完善,适合大多数项目
- 选 SWR:项目简单、只需基础数据获取、追求最小 bundle size
- 选 RTK Query:项目已使用 Redux,不想引入额外状态管理库
- 选 Apollo Client:项目以 GraphQL 为主要数据源,需要完整的 GraphQL 客户端能力
最佳实践
1. QueryKey 设计原则
// 推荐:使用数组 + 对象,确保唯一性
useQuery({ queryKey: ['users', { status: 'active', page: 1 }], queryFn: ... })
useQuery({ queryKey: ['users', userId, 'posts'], queryFn: ... })
// 避免:字符串拼接,容易冲突
useQuery({ queryKey: `users-${userId}`, queryFn: ... })2. 合理使用 staleTime
// 静态数据:长 staleTime
useQuery({
queryKey: ['config'],
queryFn: fetchConfig,
staleTime: 1000 * 60 * 60 * 24 // 24 小时
})
// 实时数据:短 staleTime + refetchInterval
useQuery({
queryKey: ['stock', symbol],
queryFn: fetchStockPrice,
staleTime: 1000 * 5,
refetchInterval: 1000 * 10 // 每 10 秒轮询
})3. Mutation 错误处理
const mutation = useMutation({
mutationFn: createUser,
onSuccess: (data) => {
toast.success('用户创建成功')
queryClient.invalidateQueries({ queryKey: ['users'] })
queryClient.setQueryData(['users', data.id], data) // 乐观更新缓存
},
onError: (error) => {
toast.error(`创建失败: ${error.message}`)
// 不需要手动回滚,Query 会自动重新获取
}
})4. 并行查询优化
// 并行获取多个相关数据
const queries = useQueries({
queries: [
{ queryKey: ['user', id], queryFn: fetchUser, enabled: !!id },
{ queryKey: ['user', id, 'posts'], queryFn: fetchUserPosts, enabled: !!id },
{ queryKey: ['user', id, 'settings'], queryFn: fetchUserSettings, enabled: !!id }
]
})
const allLoaded = queries.every(q => !q.isLoading)5. 配合 React Server Components
// Server Component:服务端获取初始数据
async function Page() {
const initialData = await fetchData()
return <ClientComponent initialData={initialData} />
}
// Client Component:接管后续数据更新
'use client'
function ClientComponent({ initialData }) {
const { data } = useQuery({
queryKey: ['data'],
queryFn: fetchData,
initialData
})
// ...
}6. 缓存失效策略
// 精准失效:只失效相关查询
queryClient.invalidateQueries({ queryKey: ['users', userId] })
// 前缀匹配:失效所有用户相关查询
queryClient.invalidateQueries({ queryKey: ['users'] })
// 精确匹配:只失效完全匹配的查询
queryClient.invalidateQueries({ queryKey: ['users'], exact: true })技术局限与边界
1. 不适合客户端纯状态管理
TanStack Query 专注于服务端状态,不应用于纯客户端状态(如 UI 开关、表单临时值)。这类场景应使用 useState、useReducer 或 Zustand / Jotai。
2. GraphQL 场景的局限
TanStack Query 可以处理 GraphQL 请求,但不提供 Apollo 那样的规范化缓存和类型推导。如果项目以 GraphQL 为核心数据源,Apollo Client 可能是更好的选择。
3. 缓存一致性复杂度
在微前端或多实例场景下,多个 QueryClient 的缓存同步需要额外设计,可能导致一致性问题。
4. 学习曲线
相比 SWR,TanStack Query 的 API 更丰富但也更复杂,新手需要理解 staleTime、gcTime、queryKey 等概念,有一定学习成本。
5. SSR / SSG 的水合复杂度
在服务端渲染场景下,需要使用 dehydrate / hydrate 手动传递缓存数据,增加了代码复杂度。TanStack Start 简化了这一流程,但并非所有项目都使用 TanStack Start。
6. 大列表性能
useInfiniteQuery 处理超大列表时,需要配合虚拟滚动(如 TanStack Virtual)才能保证渲染性能,否则可能导致性能问题。
7. 版本碎片化
v6 目前仅 Svelte 可用,React / Vue / Solid 仍在 v5,社区存在版本碎片化问题。选择框架适配器时需要注意版本差异。
学习资源
官方资源
- TanStack Query 官方文档 - 最权威的参考
- v5 迁移指南 - 从 v4 迁移的详细指南
- v5 发布公告 - v5 新功能详解
- Svelte v6 迁移指南 - Svelte v6 专属
视频教程
- TanStack Query Full Course 2026 - 2026 年最新完整教程
- TanStack React Query v5 - Full Guide - v5 详细指南
文章与博客
- React Query vs TanStack Query vs SWR: A 2025 Comparison - 2025 年对比分析
- Mastering State Management with TanStack Query v5 - 进阶状态管理
- The State of TanStack, Two Years of Full-Time OSS - TanStack 发展历程
中文资源
- TanStack Query 中文文档 - 官方中文文档
- 迁移到 TanStack Query v5 中文指南 - 中文版迁移指南
GitHub 讨论
- RFC: Unified Imperative Query Methods #9135 - v5 新增的命令式 API 讨论
- Svelte 5 Support #7413 - Svelte 5 支持讨论
2026 年现状
版本状态
截至 2026 年 6 月:
| 框架 | 当前版本 | 状态 |
|---|---|---|
| React | v5.101.0 | 稳定维护,持续更新 |
| Vue | v5.x | 稳定维护 |
| Solid | v5.x | 稳定维护 |
| Svelte | v6.1.36 | 已升级至 v6,基于 Svelte 5 Runes 重写 |
关键动态
-
TanStack Start 进入 GA:基于 TanStack Router + Query 的全栈元框架正式发布,提供类型安全的全栈开发体验
-
v5 持续演进:React 版本仍在 v5 系列,持续修复 bug 并添加新特性(如
streamedQuery),v6 尚未对 React 发布 -
供应链安全事件:2026 年 5 月遭遇 npm 供应链攻击(仅影响
react-router,不影响 Query),团队在 3 天内完成安全审计 -
默认技术栈地位巩固:TanStack Query + Zustand 组合成为 2026 年 React 项目的默认推荐技术选型
-
AI 应用支持:
streamedQuery的加入使 TanStack Query 能更好地支持 LLM 流式输出场景 -
社区持续增长:GitHub Stars 接近 5 万,周下载量超过 1200 万,生态系统不断完善
未来展望
- React v6 预计:社区已开始讨论 v6 的破坏性变更,预计 React 适配器将在 2026 年下半年至 2027 年进入 v6
- TanStack DB 集成:新的响应式客户端存储 TanStack DB 将与 Query 深度集成
- React Server Components 优化:进一步优化与 RSC 的协作模式
- 更好的流式支持:
streamedQuery将持续增强,支持更多流式场景
本文档基于 2026 年 7 月调研数据编写,信息可能随版本更新而变化。建议参考 官方文档 获取最新信息。