首页 / TanStack 生态入门教程 / DB 与 Pacer:新库概览

TanStack 生态入门教程

DB 与 Pacer:新库概览

本教程共 38 篇 · 第 38 篇 · 更新于 2026-07-27 · 约 11 分钟阅读

TanStackTanStack 生态入门教程TanStack DBTanStack PacerTanStack Rangerlive queries防抖节流

38. DB 与 Pacer:新库概览

本节目标:了解 TanStack 生态的两个新库。TanStack DB(客户端数据库、live queries、乐观更新)和 TanStack Pacer(防抖、节流、限流、队列),顺带认识 Ranger,展望生态未来。学完你对 TanStack 全生态有完整认知。

38.1 TanStack DB:客户端数据库

前面 37 章讲的库都是成熟稳定的。这一章讲的两个库还处于 v0 阶段,API 可能变动,但方向已经清晰。

Warning

TanStack DB 当前版本 v0.1.x,属于早期阶段。API 可能变动,本章内容基于 2026 年 7 月的公开信息,实际使用时请查阅最新文档。

38.1.1 DB 解决什么问题

你已经会了 TanStack Query:它管服务端数据的获取、缓存、失效。但 Query 有个短板—它把每次查询的结果当成独立的数据块,查询之间没有关系。

打个比方:Query 像是你从仓库取了一堆东西放到不同的柜子里。但你想知道「所有未完成的任务属于哪个项目」,就得自己手动翻柜子、做关联、过滤。数据量一大,前端 filter()/find()/useMemo() 满天飞,渲染卡顿。

TanStack DB 的答案是:在浏览器里放一个客户端数据库。数据进来后存成归一化的集合(Collection),然后用类似 SQL 的查询语句做关联、过滤、聚合,而且查询结果是**响应式(Live)**的—底层数据变了,查询结果自动更新。

官方的说法是:Query 管「数据怎么拿」,DB 管「数据来了之后怎么保持一致和快速」。

38.1.2 核心概念

TanStack DB 有三个核心概念:

集合(Collections):把你的 useQuery 调用包装成集合。REST、GraphQL、WebSocket 都行,数据进来后存成归一化的表。

import { createCollection } from '@tanstack/react-db'
import { queryCollectionOptions } from '@tanstack/query-db-collection'

const todoCollection = createCollection(
  queryCollectionOptions({
    queryKey: ['todos'],
    queryFn: async () => fetchTodos(),
    getKey: (item) => item.id, // 每条数据的唯一标识
    schema: todoSchema,        // 数据结构定义(用 Zod 等)
  })
)

实时查询(Live Queries):类似 SQL 的查询语句,跨集合做关联、过滤、聚合。查询结果是响应式的,底层数据变了自动更新。

import { useLiveQuery } from '@tanstack/react-db'
import { eq } from '@tanstack/db'

function TodoList() {
  // 查询未完成的任务,数据变化时自动更新
  const { data: pendingTodos } = useLiveQuery((query) =>
    query
      .from({ todos: todoCollection })
      .where(({ todos }) => eq(todos.completed, false))
  )

  return <List items={pendingTodos} />
}

乐观变更(Optimistic Mutations):直接往集合里写数据,DB 自动做乐观更新。失败了自动回滚,不用手写 onMutate/onError/onSettled 那套。

// 一行搞定,自动乐观更新、自动回滚
todoCollection.insert({
  id: crypto.randomUUID(),
  text: '新任务',
  completed: false,
})

38.1.3 为什么快:差分数据流(Differential Dataflow)

DB 的性能秘诀是差分数据流(Differential Dataflow)。简单说就是:数据变化时,不重新计算整个查询结果,只算变化的那部分。

举个例子:你有 10 万条任务,其中 1000 条是未完成的。你勾选了一条变成已完成,传统做法是重新过滤 10 万条数据。差分数据流只更新那 1 条的变化,其他 999 条未完成的不受影响,几乎零开销。

官方的数据:更新 10 万行数据中的一行,0.7 毫秒搞定。这是在浏览器里跑的,不是服务端。

Tip

差分数据流不是 TanStack 发明的,它来自数据库领域的研究。TanStack DB 把这个技术搬到了浏览器里,让前端也能享受数据库级别的查询性能。

38.1.4 和 Query 的关系

DB 不是替代 Query 的,而是在 Query 之上加了一层:

服务端 API
  ↓ useQuery(Query 管:获取、缓存、失效)
TanStack Query 缓存
  ↓ createCollection(DB 管:归一化、关联、响应式查询)
TanStack DB 集合
  ↓ useLiveQuery
组件渲染

Query 负责把数据从服务端拉到浏览器,DB 负责把数据组织好、查询好、保持一致。你可以一个集合一个集合地逐步引入,不用一次性改造整个项目。

Note

DB 适合数据量大、关联复杂、需要实时更新的场景。如果只是简单的 CRUD,用 Query 就够了。数据量上千、有跨表关联、乐观更新频繁时,DB 的价值才明显。

38.2 TanStack Pacer:时间控制工具箱

Warning

TanStack Pacer 当前版本 v0.22.x,属于 v0 阶段。API 可能变动,本章内容基于 2026 年 7 月的公开信息。

38.2.1 Pacer 解决什么问题

前端开发里有一类问题特别烦:事件太频繁,处理跟不上

  • 用户输入搜索框,每输一个字符发一次请求—服务端被刷爆。
  • 监听 scroll 事件,滚动一秒触发几十次—页面卡顿。
  • 上传文件,同时开太多并发—浏览器和服务器都扛不住。

以前你得自己写 setTimeout 防抖、Date.now() 节流、Promise.all 限流… 每个项目重复造轮子。

TanStack Pacer 把这些时间控制逻辑封装成类型安全的基础工具:防抖(Debounce)、节流(Throttle)、限流(Rate Limiting)、队列(Queuing)、批量处理(Batching)。

38.2.2 五大核心能力

防抖(Debounce):事件停了才执行。适合搜索框、自动保存、表单校验。

import { useDebouncedCallback } from '@tanstack/react-pacer'

function SearchBox() {
  // 用户停止输入 500ms 后才执行搜索
  const debouncedSearch = useDebouncedCallback(
    (value: string) => {
      searchAPI(value)
    },
    { wait: 500 }
  )

  return <input onChange={(e) => debouncedSearch(e.target.value)} />
}

节流(Throttle):固定间隔执行一次。适合滚动、缩放、指针移动。

import { useThrottledCallback } from '@tanstack/react-pacer'

function ScrollHandler() {
  // 每 100ms 最多执行一次
  const throttledScroll = useThrottledCallback(
    (scrollY: number) => {
      updateScrollPosition(scrollY)
    },
    { wait: 100 }
  )

  return <div onScroll={(e) => throttledScroll(e.currentTarget.scrollTop)} />
}

限流(Rate Limiting):限制时间窗口内的执行次数。适合 API 调用频率控制。

import { useRateLimitedCallback } from '@tanstack/react-pacer'

// 每秒最多调用 5 次
const rateLimitedFetch = useRateLimitedCallback(
  (url: string) => fetchData(url),
  { limit: 5, window: 1000 }
)

队列(Queuing):管理异步任务执行顺序。支持 FIFO/LIFO、优先级、暂停/恢复、取消、重试、并发控制。

import { AsyncQueuer } from '@tanstack/pacer'

// 最多同时上传 3 个文件
const uploadQueue = new AsyncQueuer(uploadFile, { concurrency: 3 })

uploadQueue.addItem(file1)
uploadQueue.addItem(file2)
uploadQueue.addItem(file3)
uploadQueue.addItem(file4) // 排队等前面的完成

// 暂停队列(不丢失排队中的任务)
uploadQueue.pause()
// 恢复
uploadQueue.resume()

批量处理(Batching):把多个操作合并成一次执行。适合日志上报、批量写入。

import { Batcher } from '@tanstack/pacer'

// 收集日志,每 5 秒或满 100 条时批量发送
const logBatcher = new Batcher(
  (logs) => sendLogs(logs),
  { maxSize: 100, wait: 5000 }
)

logBatcher.addItem('用户点击了按钮')
logBatcher.addItem('用户打开了菜单')
// 这些日志会被批量发送,而不是一条条发

38.2.3 Pacer 的特点

  • 同步和异步都支持:防抖节流既支持同步函数,也支持异步函数。异步版有额外的状态(pending、success、error)。
  • 可观察的状态:每个工具都暴露状态(是否在等待、是否在执行、排队了多少个),可以绑到 UI 上显示。
  • 手动控制:不只是被动等待,可以手动 flush(立即执行)、cancel(取消)、pause/resume(暂停恢复)。
  • 框架适配器:核心逻辑框架无关,React/Solid/Vue/Angular 都有适配器。
Tip

Pacer 和第 33 章讲的 Form 内置防抖不同。Form 的 onChangeAsyncDebounceMs 只用于表单校验。Pacer 是通用的时间控制工具,任何场景都能用。

38.2.4 和 Form 校验防抖的对比

Form 里的防抖:

// Form 内置,只用于校验
<form.Field
  validators={{
    onChangeAsyncDebounceMs: 500,
    onChangeAsync: async ({ value }) => { ... }
  }}
>

Pacer 的防抖:

// 通用,任何回调都能防抖
const debouncedFn = useDebouncedCallback(fn, { wait: 500 })

两者不冲突。Form 校验用 Form 内置的,其他场景用 Pacer。

38.3 TanStack Ranger 简介

TanStack 还有个叫 Ranger 的小库,专门做范围滑块(Range Slider)

Warning

Ranger 当前版本 v0.0.5,极早期。功能可能不完整,生产慎用。

import { useRanger } from '@tanstack/react-ranger'

function RangeSlider() {
  const ranger = useRanger({
    min: 0,
    max: 100,
    stepSize: 5,
    values: [25, 75],
    onChange: (values) => console.log(values),
  })

  // 用 ranger 提供的数据自己渲染滑块 UI
}

Ranger 也是 headless 的—只管滑块的数值计算和交互逻辑,UI 你自己画。适合需要自定义滑块样式的场景。但目前极早期,功能有限,教程里知道有这个东西就行。

38.4 TanStack 生态全景

38 章走下来,TanStack 生态的版图已经清晰了:

定位成熟度章节
Query服务端状态管理稳定 v54-14
Router类型安全路由稳定 v115-21
Start全栈框架v1 RC22-25
Tableheadless 表格稳定 v826-31
Formheadless 表单稳定 v132-34
Virtual虚拟化列表稳定 v335-36
Store响应式状态管理v0.1137
DB客户端数据库v0 早期38
Pacer时间控制工具v038
Ranger范围滑块v0.0.5 极早期38

三个核心理念贯穿整个生态:

  1. headless(无头):Table、Form、Virtual、Ranger 都是只管逻辑不管 UI。你完全掌控样式。
  2. 框架无关(Framework-agnostic):核心逻辑不依赖任何框架,React/Vue/Solid/Svelte/Angular 都有适配器。
  3. 类型安全(Type-safe):从 Router 的路由参数到 Table 的列定义,从 Form 的字段值到 Store 的状态,全链路 TypeScript 类型推导。

38.5 选型建议

面对这么多库,怎么选?

服务端数据:TanStack Query 是必选。几乎所有 React 项目都受益。

路由:新项目、用 TypeScript、重视类型安全,选 TanStack Router。老项目已经在 React Router 上跑着,没强需求不用换。

全栈:要 SSR、Server Functions、全栈一体化,用 TanStack Start(内置 Router)。

表格:需要高度定制、轻量、免费,用 TanStack Table。要开箱即用、功能全(Excel 导出、透视表),用 ag-Grid。

表单:字段多、校验复杂、要类型安全,用 TanStack Form。简单表单 useState 就行。

长列表:数据量上千、滚动卡顿,用 TanStack Virtual。

全局状态:轻量需求用 TanStack Store。复杂状态管理 Redux/Zustand 也行。

客户端数据库:数据量大、关联复杂、需要实时更新,关注 TanStack DB(还在 v0)。

时间控制:防抖节流限流队列,用 TanStack Pacer(还在 v0,也可用 lodash.debounce 等替代)。

38.6 生态展望

TanStack 生态还在快速演进:

  • DB 和 Pacer 正在从 v0 走向稳定,一旦 1.0 发布,整个生态的客户端数据层和时间控制能力会大幅提升。
  • Table v9 已在 beta 中,API 有调整(useReactTable -> useTable + tableFeatures),但 v8 仍是当前稳定版。
  • Store 的 atom 机制在持续完善,未来可能成为整个生态统一的响应式原语。
  • Start 在全栈方向上持续迭代,SSR、部署、DX 都在改善。

TanStack 的理念一直没变:headless、框架无关、类型安全。这套理念让它的库既有底层控制力,又能跨框架复用。学一套理念,受益多个库。

Note

技术选型没有银弹。TanStack 的库在类型安全和灵活性上很强,但学习曲线比「开箱即用」的库陡。根据项目需求权衡,别为了用而用。

38.7 小结

这是整个教程的最后一章。你了解了:

  • TanStack DB:客户端数据库,用集合(Collections)存数据、实时查询(Live Queries)做关联过滤、乐观变更做自动回滚。底层用差分数据流实现毫秒级增量更新。
  • TanStack Pacer:时间控制工具箱,防抖、节流、限流、队列、批量处理五大能力。同步异步都支持,状态可观察,可手动控制。
  • TanStack Ranger:范围滑块库,极早期,知道有就行。
  • 生态全景:10 个库,三大理念(headless、框架无关、类型安全),从数据获取到路由到全栈到表格表单到虚拟化到状态管理,覆盖前端开发方方面面。

38 章的旅程到此结束。从 Query 的第一个 useQuery 开始,到 DB 的差分数据流结束,你走完了 TanStack 生态的完整版图。剩下的就是在项目里实践、踩坑、成长。祝你好运。

上一篇
Store:响应式状态管理
下一篇
已经是最后一篇啦