TanStack Query 起源与概述

TanStack Query 的起源、历史背景、核心定位与生态全景。从 React Query 到 TanStack Query 的演变,以及它解决的核心问题。

#type / concept #status / evergreen #tech / dev / frontend #resource / react

[!info] related notes

TanStack Query 起源与概述

一句话定位

TanStack Query 是一个异步状态管理库,专注于解决 React 应用中服务端数据的获取、缓存、同步与失效问题。它不是传统的”请求库”,而是把服务端数据当作一种有生命周期的状态来管理。

历史背景

从 React Query 到 TanStack Query

时间事件
2019Tanner Linsley 发布 react-query,解决 React 中数据获取的痛点
2020v2 发布,引入 queryKey 缓存机制,社区快速增长
2021v3 发布,引入 QueryClient、结构化 queryKey、无限查询等重大改进
2022重命名为 @tanstack/react-query,v4 发布,底层架构重构
2023品牌统一为 TanStack,推出框架无关的核心 @tanstack/query-core,支持 React/Vue/Solid/Angular/Svelte
2024v5 发布,引入 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 ClientGraphQL 状态管理专为 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
创建于 2026/7/3 更新于 2026/7/15