SuperAPI AI 工具集

tanstack-db-core-mutations-optimistic

数据与分析

查看项目

更新于 10-16 09:23

技能介绍

用途

本技能面向使用 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 等待持久化或捕获回滚错误。

核心模式

  1. createOptimisticAction:基于意图的变更,适用于乐观变更是对服务器如何转换数据的猜测,或需要原子地变更多个集合的场景。onMutate 必须同步(在当前 tick 应用),mutationFn 中需等待服务器状态同步回写后再返回。

  2. createPacedMutations:自动保存,支持 debounceStrategy(防抖)、throttleStrategy(节流,适用于滑块、滚动)、queueStrategy(顺序 FIFO,每条变更按序持久化)。

  3. createTransaction:手动批量。autoCommit: false 时等待显式 commit()。在 tx.mutate(() => { ... }) 内,事务被压入环境栈,任何 collection.insert/update/delete 会通过 getActiveTransaction() 自动加入环境事务。被手动事务捕获的变更不会自动调用集合级 onInsert/onUpdate/onDelete 处理器,需由手动事务的 mutationFn 负责持久化 transaction.mutations。适合草稿式流程:本地状态立即更新,服务器调用等待保存/失焦,可用 tx.rollback() 丢弃乐观变更。

  4. 带 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。