用途
本技能面向使用 TanStack DB 的开发者,聚焦集合(collection)的写操作与乐观状态管理。使用前需先完成 db-core/collection-setup:配置好 collection(含 getKey、sync 适配器,以及可选的 onInsert/onUpdate/onDelete 处理器)。
TanStack DB 的变更遵循单向循环:乐观变更 → 处理器持久化到后端 → 同步回写 → 确认状态。乐观状态在当前 tick 应用,并在处理器 resolve 时丢弃。
主要能力
集合写操作
insert 支持单条、多条、带 metadata 以及 { optimistic: false } 非乐观写入。
update 使用 Immer 风格草稿代理:传入 id 与回调,在回调中修改 draft,不要重新赋值。支持单条、多条(drafts 数组)以及带 metadata 的写法。
delete 支持单条、多条以及带 metadata。
三者均返回 Transaction 对象,可用 tx.isPersisted.promise 等待持久化或捕获回滚错误。
核心模式
-
createOptimisticAction:基于意图的变更,适用于乐观变更是对服务器如何转换数据的猜测,或需要原子地变更多个集合的场景。onMutate 必须同步(在当前 tick 应用),mutationFn 中需等待服务器状态同步回写后再返回。
-
createPacedMutations:自动保存,支持 debounceStrategy(防抖)、throttleStrategy(节流,适用于滑块、滚动)、queueStrategy(顺序 FIFO,每条变更按序持久化)。
-
createTransaction:手动批量。autoCommit: false 时等待显式 commit()。在 tx.mutate(() => { ... }) 内,事务被压入环境栈,任何 collection.insert/update/delete 会通过 getActiveTransaction() 自动加入环境事务。被手动事务捕获的变更不会自动调用集合级 onInsert/onUpdate/onDelete 处理器,需由手动事务的 mutationFn 负责持久化 transaction.mutations。适合草稿式流程:本地状态立即更新,服务器调用等待保存/失焦,可用 tx.rollback() 丢弃乐观变更。
-
带 refetch 的变更处理器(QueryCollection 模式):onInsert/onUpdate/onDelete 中调用 API 后,处理器必须等到服务器状态同步回写才能 resolve,QueryCollection 会在处理器完成后自动 refetch。ElectricCollection 则返回 { txid } 而非 refetch。
常见错误
- 向 update() 传对象而非草稿回调:会静默失败或抛错,应使用 (draft) => { draft.title = 'new' }。
- 臆造变更 API 签名:如虚构集合配置上的 onMutate、混淆 createOptimisticAction 与 createTransaction、写错 PendingMutation 属性名(不存在 mutation.data,应使用 mutation.modified、mutation.changes、mutation.original)、遗漏环境事务模式。应参考 references/transaction-api.md 中的确切类型。
- onMutate 返回 Promise:createOptimisticAction 的 onMutate 必须同步,返回 Promise 会抛 OnMutateMustBeSynchronousError。
- 变更缺少处理器或环境事务:集合变更需要 onInsert/onUpdate/onDelete 处理器,或来自 createTransaction/createOptimisticAction 的环境事务,否则抛 MissingInsertHandlerError(或 Update/Delete 变体)。
- 事务不再 pending 时调用 .mutate():commit() 或 rollback() 后调用会抛 TransactionNotPendingMutateError,应新建事务。
- 通过 update 修改主键:update 代理会检测键变化并抛 KeyUpdateNotAllowedError,主键一旦设置不可变,需删除后重新插入。
- 插入重复键:已存在同键项(已同步或乐观)会抛 DuplicateKeyError,应生成唯一键(如 crypto.randomUUID())或插入前检查。
- query collection 处理器中变更后未等待 refetch:乐观状态仅保持到处理器 resolve,若处理器在服务器状态同步回写前返回,乐观状态被丢弃,用户会看到数据缺失的闪烁。
适用场景
需要即时反馈的交互(点赞、自动保存笔记、草稿编辑)、需要原子变更多个集合的操作、需要防抖/节流/队列控制的自动保存,以及需要手动批量提交或回滚的草稿式流程。
限制与权衡
即时乐观更新会产生客户端状态与服务器状态分歧的窗口。若处理器失败,回滚会移除乐观状态,可能丢弃用户以为已保存的工作。可考虑:显示 pending/saving 指示;对破坏性操作使用 { optimistic: false };设计幂等的服务器端点以便安全重试;处理 tx.isPersisted.promise 的 rejection 以向用户暴露错误。
参考
Transaction API Reference(createTransaction 配置、Transaction 对象、PendingMutation 类型、变更合并规则、策略类型)与 TanStack DB Mutations Guide。