TanStack Query 起源与概述
TanStack Query 的起源、历史背景、核心定位与生态全景。从 React Query 到 TanStack Query 的演变,以及它解决的核心问题。
#type / concept
#status / evergreen
#tech / dev / frontend
#resource / react
[!info] related notes
- 所属 MOC: TanStack Query 知识地图
- 入门: TanStack Query 服务端状态
- 架构: 四层状态架构
- 对比: Zustand 全局状态
TanStack Query 起源与概述
一句话定位
TanStack Query 是一个异步状态管理库,专注于解决 React 应用中服务端数据的获取、缓存、同步与失效问题。它不是传统的”请求库”,而是把服务端数据当作一种有生命周期的状态来管理。
历史背景
从 React Query 到 TanStack Query
| 时间 | 事件 |
|---|---|
| 2019 | Tanner Linsley 发布 react-query,解决 React 中数据获取的痛点 |
| 2020 | v2 发布,引入 queryKey 缓存机制,社区快速增长 |
| 2021 | v3 发布,引入 QueryClient、结构化 queryKey、无限查询等重大改进 |
| 2022 | 重命名为 @tanstack/react-query,v4 发布,底层架构重构 |
| 2023 | 品牌统一为 TanStack,推出框架无关的核心 @tanstack/query-core,支持 React/Vue/Solid/Angular/Svelte |
| 2024 | v5 发布,引入 Suspense 原生支持、改进的 mutation API、gcTime 替代 cacheTime |
| 2025-2026 | 持续迭代,成为 React 生态中服务端状态管理的事实标准 |
为什么叫 TanStack
Tanner Linsley(作者)将自己的一系列开源项目统一到 TanStack 品牌下:
- TanStack Query — 异步状态管理(原 React Query)
- TanStack Router — 类型安全的路由(原 React Location)
- TanStack Table — 表格库(原 React Table)
- TanStack Form — 表单库
- TanStack Virtual — 虚拟化列表
核心理念:框架无关。@tanstack/query-core 是纯 TypeScript 实现,各框架的适配层(@tanstack/react-query、@tanstack/vue-query 等)只是薄薄的绑定层。
它解决什么问题
传统方式的痛点
// 典型的 useEffect + useState 模式
const [data, setData] = useState(null);
const [isLoading, setIsLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
let cancelled = false;
setIsLoading(true);
fetch('/api/users')
.then(r => r.json())
.then(data => {
if (!cancelled) {
setData(data);
setIsLoading(false);
}
})
.catch(err => {
if (!cancelled) {
setError(err);
setIsLoading(false);
}
});
return () => { cancelled = true; };
}, []);
这段代码缺失了:
- 缓存:切换页面回来又重新请求
- 去重:两个组件同时请求同一数据,发了两次
- 后台刷新:数据过期后如何自动更新
- 窗口聚焦刷新:用户切走再切回来时数据可能已过期
- 重试:网络抖动时自动重试
- 乐观更新:mutation 后立即反映到 UI
- 竞态处理:快速切换参数时旧请求覆盖新数据
TanStack Query 的解法
const { data, isLoading, error } = useQuery({
queryKey: ['users'],
queryFn: () => fetch('/api/users').then(r => r.json()),
});
一行代码,上面所有问题都被内置解决了。
核心概念速览
| 概念 | 作用 | 详见 |
|---|---|---|
useQuery | 获取并缓存服务端数据 | tanstack-query-server-state |
useMutation | 执行写操作(POST/PUT/DELETE) | tanstack-query-server-state |
queryKey | 缓存键,决定数据归属和重新获取时机 | tanstack-query-query-key-factory |
QueryClient | 缓存容器,管理所有 query 的生命周期 | tanstack-query-client-configuration |
staleTime | 数据”新鲜”的持续时间 | tanstack-query-gctime-vs-staletime |
gcTime | 缓存数据在无订阅后的保留时间 | tanstack-query-gctime-vs-staletime |
invalidateQueries | 标记缓存过期,触发重新获取 | tanstack-query-cache-invalidation-patterns |
setQueryData | 直接写入缓存 | tanstack-query-cache-invalidation-patterns |
生态位置
┌─────────────────────────────────────────────┐
│ React 应用状态 │
├──────────────────┬──────────────────────────┤
│ 客户端状态 │ 服务端状态 │
│ Zustand / Redux │ TanStack Query │
│ UI 状态、表单 │ API 数据、缓存 │
│ 认证 token │ 列表、详情、分页 │
└──────────────────┴──────────────────────────┘
与同类工具的定位差异:
| 工具 | 定位 | 特点 |
|---|---|---|
| TanStack Query | 服务端状态管理 | 缓存、失效、后台刷新、乐观更新 |
| SWR | 服务端状态管理 | 更轻量,API 更简单,功能较少 |
| RTK Query | 服务端状态管理 | Redux 生态内的方案 |
| Zustand | 客户端状态管理 | 管理 UI 状态、表单、认证 |
| Apollo Client | GraphQL 状态管理 | 专为 GraphQL 设计,内置规范化缓存 |
版本选择
当前推荐使用 v5(@tanstack/react-query@5.x):
- 原生 Suspense 支持
- 更好的 TypeScript 类型推导
gcTime替代cacheTime(语义更清晰)- 改进的 mutation API
- 更小的包体积
# 安装
npm install @tanstack/react-query
# DevTools(开发时推荐)
npm install @tanstack/react-query-devtools
适用场景
适合用 TanStack Query 的场景:
- 从 API 获取的列表/详情数据
- 需要缓存避免重复请求
- 需要 loading/error 状态管理
- 需要后台自动刷新
- 需要乐观更新
- 分页、无限滚动
不适合的场景:
- 纯客户端状态(UI 开关、表单草稿)→ 用 useState / Zustand
- 实时 WebSocket 数据流 → 用专门的 WebSocket 管理
- GraphQL → 考虑 Apollo Client 或 urql
- 静态数据 → 直接 import