React Actions 与并发一致性
并发界面不是“几个请求同时跑”这么简单,而是给每个操作和快照确定身份:哪个提交正在进行、哪层是暂时预测、哪个结果有资格写回、一次屏幕提交是否来自同一版外部数据。
核心模型
并发界面不是“几个请求同时跑”这么简单,而是给每个操作和快照确定身份:哪个提交正在进行、哪层是暂时预测、哪个结果有资格写回、一次屏幕提交是否来自同一版外部数据。
原理与机制
Action 整理提交,不建立服务端事务
useActionState 返回 state、dispatchAction、isPending,action 接收前次状态和本次载荷;表单 action 或 formAction 建立 Action 上下文,手动 dispatch 需放进 startTransition。字段校验适合返回结构化错误,异常走错误边界。useFormStatus 读取其上层表单,必须放到该 form 内部子组件,而不是定义表单组件的同一顶层。函数 action 正常完成会重置非受控字段,返回业务错误也属于正常返回,因此要明确草稿保存。服务器仍须校验身份、权限、字段、幂等与版本。
乐观状态是有归属的暂时覆盖
每次用户意图生成一次 clientId 或 mutationId,重试复用它;临时项与服务端 ID 分开。useOptimistic 的更新应处在 Action 中,更新函数纯净,成功结果还要写进持久的基准状态,临时层不是数据库。确认按操作身份替换,失败只撤销自己的预测,不能恢复整个旧列表而抹掉别人的成功。创建后又编辑需要额外修订号,防止迟到创建回执盖回旧文本。客户端去重只整理 UI,服务端仍需自己的幂等协议。
Transition 调整渲染优先级
文本输入仍应立即响应,让昂贵结果用过渡更新或 deferred 值追赶。startTransition 的回调立即运行,里面的大 JSON.parse、排序或循环不会被搬到另一线程;先解决算法、分片或 Worker。当前 React 文档要求 await 后需要标记的 setState 再包一次 startTransition,自己管理请求仍需处理乱序。Transition 不是防抖,不承诺减少请求,也不自动取消已发工作。旧结果暂留时要明确过期,涉及权限与金额的操作另行验证。
外部 store 提供可比较的版本快照
useSyncExternalStore 以 subscribe、getSnapshot 和可选的 getServerSnapshot 建立同步契约,覆盖渲染到订阅之间的窗口并支持一致提交。未变时快照引用稳定,变更后返回新不可变快照;每次 getter 新建对象可能循环,原地改同对象又可能漏更新。SSR 初始快照在服务端和客户端水合必须一致。Transition 提交前若外部快照变化,React 可以重启为阻塞更新,确保屏幕同版;把外部写入包在 startTransition 并不会使其自动成为非阻塞更新。
操作顺序也要成为明确契约
同一个 useActionState 的 dispatch 会排队调用 action,把前一次结果传给下一次,这不意味着不同表单或不同 Hook 拥有全局顺序。独立并行操作仍需 ID、提交版本和冲突策略。选择“保存草稿”或“发布”时把 intent 作为服务端校验的数据,而不是只靠按钮文案;父 form 的 pending 也不等于每个按钮各有独立请求状态。最后将模拟乱序、重放与超时后的状态列成表,确认任何迟到回执都不能清掉新草稿。
最小示例
jsx假定 save 是已定义的异步保存函数,返回服务端规范化名称。Submit 确实是 form 的后代,因此读到正确 pending。受控草稿不会因非受控字段的自动重置丢失,保存后的名称只展示为回执,也不覆盖用户等待期间的新编辑。真实应用须区分预期服务端校验错误与异常、标明“已保存版本”,并测试重复提交。
环境:React 19 与 react-dom JSX 项目;save 是调用方提供的异步保存函数,返回规范化名称,服务端验证及外层错误边界由应用实现。
核验:已静态审查示例与本章机制一致;未运行此示例,未进行框架或浏览器集成测试。观察结果为待复现的教学预期。
边界与取舍
边界
- Action、乐观 Hook 与禁用按钮不提供后端授权、幂等或数据库回滚,客户端取消也不代表服务器撤销。
- Transition 能协调可中断渲染,却不能中断单次同步解析,也不自动解决请求乱序。
- 外部 store 不能靠同引用原地修改表达新版本;不同用户的 SSR 快照也不能共享可变单例。
取舍
- 乐观反馈显得更快,却需要操作身份、版本与局部回滚;高失败率或高后果操作宜先确认事实。
- 不可变快照便于一致性与比较,却有复制成本;用版本化缓存和合适订阅粒度控制成本。
口述示范
我用 Action 组织提交状态,但把权限与幂等留在服务端;乐观更新是带操作 ID 的临时层,确认更新基准,失败仅回滚自己。Transition 优化渲染调度,不能替代计算优化。外部 store 用稳定不可变快照,并接受一致性需要时回退阻塞。
章节练习
参考来源与核验边界
- React:useActionState · 核验 2026-10-04
- React:useOptimistic · 核验 2026-10-04
- React:useTransition · 核验 2026-10-04
- React:useSyncExternalStore · 核验 2026-10-04
按 React 19 系列 API 与核验日官方文档;明确保留 await 后再次包 startTransition 的现有限制。函数表单 action 的正常完成会重置非受控字段,须在实际 React 版本回归验证。
内容版本:2026-10-04.2 · 题目和来源 ID 保持原样,本站不将面经标签解释为企业官方出题或高频保证。