开始使用 TanStack DB 构建响应式 UI

构建响应式 UI 不应该在性能和简洁性之间做出选择。然而,现代 JavaScript 应用程序中的每次状态更新都会触发级联重渲染、复杂的记忆化处理以及充满样板代码的乐观更新。TanStack DB 彻底改变了这一局面。
本文介绍 TanStack DB——一个客户端数据库层,它通过集合(collections)、实时查询(live queries)和差分数据流(differential dataflow)扩展了 TanStack Query,实现亚毫秒级更新。您将了解到它如何简化相比 Redux 或手动缓存的状态管理,以及如何在现有项目中渐进式地采用它。
注意: TanStack DB 目前处于 beta 阶段(截至 2025 年底)。虽然 API 可能会演进,但它已经足够稳定,可以在非关键功能中进行探索和渐进式采用。
核心要点
- TanStack DB 通过关系型能力和差分数据流扩展了 TanStack Query,实现亚毫秒级 UI 更新
- 集合(Collections)封装现有查询,同时支持跨数据图的响应式连接和过滤
- 实时查询在数据变化时自动更新,无需手动缓存失效或记忆化处理
- 支持渐进式采用——从一个集合开始,无需重写即可逐步迁移
什么是 TanStack DB?
TanStack DB 是一个构建在 TanStack Query 之上的响应式客户端存储。虽然 TanStack Query 擅长获取和缓存服务器状态,但它将每个查询结果视为独立的缓存条目。TanStack DB 添加了缺失的关系层——支持跨整个数据图的连接、过滤和响应式更新。
其魔力在于差分数据流,这是一种只重新计算实际发生变化的查询部分的技术。这意味着在一个包含 100,000 项的集合中更新一行仅需 0.7 毫秒(在 M1 Pro 上)——足够快以完全消除 UI 卡顿。
核心概念:集合、实时查询和乐观变更
集合:您的数据基础
集合是类型化的对象集,可以从任何来源填充——REST API、GraphQL 或像 ElectricSQL 这样的同步引擎。它们封装您现有的 useQuery
调用:
const todoCollection = createCollection(
queryCollectionOptions({
queryKey: ['todos'],
queryFn: async () => api.todos.getAll(),
getKey: (item) => item.id,
schema: todoSchema
})
)
这看起来很熟悉,因为它基于 TanStack Query 的模式构建。区别在哪?集合会规范化您的数据,并支持跨关系的响应式查询。
实时查询:无样板代码的响应式
实时查询在底层数据变化时自动更新——无需手动缓存失效,无需 useMemo
链:
const { data: activeTodos } = useLiveQuery((query) =>
query
.from({ todos: todoCollection })
.where(({ todos }) => eq(todos.completed, false))
)
当任何待办事项的状态改变时,此查询会在 1 毫秒内更新。差分数据流引擎确保只重新计算受影响的行,而不是整个数据集。
乐观变更:即时 UI 更新
TanStack DB 自动处理乐观更新,失败时内置回滚机制:
// 之前:使用 TanStack Query 手动乐观更新
const mutation = useMutation({
mutationFn: createTodo,
onMutate: async (newTodo) => {
// 20+ 行样板代码...
}
})
// 之后:TanStack DB
todoCollection.insert({
id: uuid(),
text: 'Ship faster',
completed: false
})
变更立即出现在您的 UI 中,如果服务器拒绝,会自动回滚。无样板代码,无手动状态管理。
Discover how at OpenReplay.com.
为什么差分数据流改变一切
传统的状态管理强制进行权衡:要么进行多次 API 调用(网络慢),要么在客户端过滤大型数据集(渲染慢)。差分数据流提供了第三种选择:一次性加载规范化数据,然后在浏览器中执行闪电般快速的增量连接。
像 Linear 和 Figma 这样的公司通过定制构建的差分更新系统实现其即时 UI。TanStack DB 将这种方法民主化,使任何 JavaScript 应用程序都能实现亚毫秒级响应性。
使用 ElectricSQL 实现本地优先同步
虽然 TanStack DB 与 REST 和 GraphQL 配合良好,但与同步引擎配对时才真正发光。例如,ElectricSQL 使用 Postgres 逻辑复制将变更直接流式传输到客户端:
const todoCollection = createCollection(
electricCollectionOptions({
shapeOptions: {
url: 'http://localhost:3003/v1/shape',
params: { table: 'todos' }
},
getKey: (item) => item.id
})
)
现在对 Postgres 数据库的任何更改都会立即更新所有连接的客户端——无需 WebSocket 管道,无需手动广播。这种本地优先同步模式完全消除了用户交互中的网络延迟。
渐进式采用路径
TanStack DB 在您现有的 TanStack Query 设置之上分层。从一个集合开始,保留当前的 API 调用,然后渐进式迁移:
- 将现有查询封装到集合中
- 用实时查询替换过滤数组
- 通过自动乐观更新简化变更
- (可选)使用 ElectricSQL 添加实时同步
每一步都能提高性能并降低复杂性。无需大规模重写。
结论
TanStack DB 将差分数据流引入 JavaScript,实现以微秒而非毫秒更新的响应式 UI。通过集合和实时查询扩展 TanStack Query,它消除了网络效率和渲染性能之间的传统权衡。
虽然仍处于 beta 阶段,TanStack DB 已准备好进行探索和渐进式采用。从非关键功能中的单个集合开始,体验亚毫秒级更新为应用程序带来的不同感受。您的用户——以及您的代码库——都会感谢您。
常见问题
是的,TanStack DB 可以替代 Redux 或 Zustand 进行客户端状态管理。它通过集合和实时查询处理服务器和客户端状态。但是,建议渐进式采用以最小化 beta 阶段的风险。
与专注于数据库抽象的 ORM 不同,TanStack DB 是一个具有差分数据流的响应式客户端存储。它在浏览器中运行,无需服务器往返即可实现亚毫秒级更新,同时保持类型安全和关系型能力。
当服务器变更失败时,TanStack DB 会自动回滚乐观更新。UI 会恢复到之前的状态,无需手动干预。您可以选择添加错误处理程序以显示用户反馈或重试逻辑。
虽然处于 beta 阶段,TanStack DB 对于非关键功能的渐进式采用已经足够稳定。从隔离的组件开始,随着信心增强扩大使用范围。即使特定 API 可能在稳定版本发布前演进,核心概念也是可靠的。
Gain Debugging Superpowers
Unleash the power of session replay to reproduce bugs, track slowdowns and uncover frustrations in your app. Get complete visibility into your frontend with OpenReplay — the most advanced open-source session replay tool for developers. Check our GitHub repo and join the thousands of developers in our community.