前置:React 组件、Hooks、数组变换、Promise 和 fetch;能区分请求失败与 HTTP 非成功状态。
服务器数据会变化,页面怎样知道显示的是哪一份结果?
TanStack 是一组可组合的库。Query 管请求结果,Table 管表格行为,Router 管地址与导航,Form 管输入与校验。先分清各自状态归属,再组合;它们并不是一个必须一次装齐的框架。
服务端数据与本地输入 → queryKey → 加载/成功/失败 → mutation 与失效 → 表格 → 路由参数 → 表单
| 概念 | 必要解释 |
|---|---|
| queryKey | 是结果的身份。不同用户或不同筛选条件需要不同键,否则两份请求可能共用错误结果。 |
| staleTime 与 gcTime | 前者讨论数据多久算新鲜,后者讨论无人使用的缓存保留多久;不是一条从新鲜走到删除的必经流水线。 |
| Headless | 库给出状态与操作,你负责按钮、表头、样式和可访问性;没有默认界面不等于没有行为。 |
开始前先用普通 fetch 读取一个列表,并能显示请求中、失败、无数据三种情况。随后使用 Query 完成同一任务,比较哪些状态和重试逻辑由库负责。
下面前三篇是共同起点。Table、Router、Form 按实际页面需要选学;完成简单读写后再学习乐观更新和无限查询。版本见模块 README,依赖锁文件中的主版本必须与所查文档一致。官方概念入口:TanStack Query React Overview。
- 环境搭建与项目初始化
- Headless 设计哲学
- Query 基础:useQuery 与 useMutation
- Table 基础:列模型与数据行
- Router 基础:路由树、文件式路由与导航
- Form 基础:useForm 与字段绑定
- Query 高级特性:乐观更新、无限查询与失效策略
- 第一个项目:城市天气数据面板
完成 Query 基础后,先交付 城市天气面板 的读取与排序阶段,再做写入项目。天气面板还需要 Table 基础;Router、Form 和乐观更新不属于这个最小阶段的前置。产物是能启动的 React 工程、依赖锁文件,以及记录加载、失败、空列表、成功与排序结果的验收说明。这个面板使用模拟天气,不能作为真实天气查询产品。
接着进入 Todo 项目 前,先确认 /api/todos 已有实现:创建后再次 GET 能读回同一条记录。该项目的前端片段不会自动提供后端;尚无接口时先完成 Node.js 首项目,再按 Todo 文档的字段、路径和方法核对契约,不能假设两个示例可直接对接。没有可读回的接口时,暂留在读取阶段,不把一次模拟成功响应当作写入完成。
遇到缓存不更新,带着请求与 queryKey 回查 Query 框架要点,只修改键或失效范围中的一个因素,再重做创建与 GET。完成写入验收后,下一步是 数据看板 的筛选与分页;需要立即反馈时再增加 乐观更新 的失败回滚练习。
| 阶段与入口 | 练习输入与动作 | 通过条件 |
|---|---|---|
| 读取:Query 基础 | 用同一接口分别返回延迟结果、错误、空列表与有数据列表 | 四种界面都能主动复现,重试不会产生无法解释的重复提示 |
| 写入:Todo 项目 | 新增标题后重新查询;再模拟写入失败 | 成功后目标列表更新;失败时保留可重试输入。模拟接口若不保存数据,必须明确这一限制 |
| 筛选:数据看板 | 在两个筛选条件间来回切换,再刷新页面 | 请求参数和 queryKey 使用相同筛选值,不串用缓存;若要求分享 URL,刷新后能恢复筛选。先完成普通更新,再增加乐观回滚 |
每阶段保留实际输入、输出和一个失败案例。只阅读或复制成功代码,不等同于已经通过验收。练习用小功能承接已学知识,大型项目的扩展需求可按需选做。
先掌握 Query 再按场景选 Table、Router、Form。Next.js 已管理路由时不为了“全家桶”再引入一套路由。框架升级前核对版本与迁移文档。
关键词与完整语法实验解释语言语法;内置对象、方法与边界解释数组、字符串、对象、集合和 Promise。先区分语言、宿主 API 与框架函数,再查本模块特有内容。
关键词解决“语法是什么意思”,内置函数解决“直接能调用什么”,标准库解决“导入以后能做什么”。框架 API 另列,避免把库函数误当成语言本身。以下是现有文章的完整导航,不代表每个 API 都已充分讲解;具体覆盖缺口进入审查台账。
- Query 框架要点:缓存键、staleTime/gcTime、失效与重试
- Router 框架要点:守卫、预加载、嵌套布局与 SSR 集成
- QueryClient 全局配置:defaultOptions 与网络模式
- 预取与 SSR 水合:prefetch、dehydrate 与流式预取
- Mutation 状态与副作用:useMutationState 与 MutationCache
- Start Server Functions:createServerFn 全解
- Query 核心 API
- Table 核心 API
- Router 核心 API
- Form 核心 API
- TypeScript 模式
- 乐观更新:onMutate 快照与回滚
- 无限查询:useInfiniteQuery 与游标分页
- 占位数据:placeholderData 与 isPlaceholderData
- Suspense 查询:useSuspenseQuery 与数据保证
- 网络模式与离线支持:networkMode
- URL 搜索参数状态:validateSearch 与类型化 search
- useQueries:并行与动态查询列表
- useIsFetching / useIsMutating / useMutationState:全局加载指示器
- 缓存持久化:PersistQueryClientProvider 与按条目持久化
- 条件与依赖查询:enabled 与 skipToken
- 渲染优化:select、notifyOnChangeProps 与 structuralSharing
- FlexRender:Table 渲染入口与单元格上下文
- 受控状态:state 切片与 OnChangeFn 回调
- Outlet 与路由组件:notFoundComponent / errorComponent / pendingComponent
- useMatch / useMatches / router.invalidate:匹配读取与刷新重校验
- useField 与 createFormHook:字段复用与表单工厂