React 19 带来的变化里,最让我觉得“终于来了”的,不是 Server Components,也不是新的编译器,而是三个专门处理表单和乐观更新的 Hook:useActionState、useFormStatus 和 useOptimistic。它们把过去需要手动维护 loading、error、pending 状态的脏活,真正变成了框架层的内置能力。但如果你只是扫一眼 API 文档,很容易觉得“不过就是语法糖”,真正用起来才会发现,这些 Hook 背后的设计假设和边界,比表面看起来要深得多。

这篇文章不会逐行翻译文档,而是想从工程角度聊聊:为什么 React 19 要这样设计表单交互?这三个 Hook 分别解决什么问题,组合起来又能做什么?以及,在实际项目里有哪些容易踩到的坑。
表单不再是“用 state 驱动”这么简单
在 React 18 及以前,我们处理表单提交的典型模式是:用 useState 维护表单值、用一个独立的 isLoading 状态控制按钮禁用、用 try/catch 处理错误、还得手动清空表单或保持提交状态。这种模式在小型表单里没问题,但一旦涉及多个并发的异步操作、或者需要乐观更新,状态管理就会迅速膨胀。
React 19 的思路变了。它不再把表单提交看作一个纯粹的前端状态问题,而是把异步操作(尤其是 Server Actions)和 UI 状态直接绑定。也就是说,表单的 action 不再只是一个 URL,它可以是一个函数;而 Hook 则负责把这个函数的执行过程,透明地映射到一组可消费的状态上。这种设计让表单的行为更接近原生 HTML 的简单性,同时又保留了 React 的声明式风格。
useFormStatus:读取表单提交状态,但别用错地方
useFormStatus 的作用很直接:返回当前表单的 pending 状态,以及正在提交的数据和 action。但它的第一个关键限制是——必须在