React 19 Actions 实战:简化异步表单处理全流程

2 阅读1分钟

目录 (Outline)


一、Actions 的核心哲学

Action 的本质是一个增强版的异步函数

  • 自动挂钩状态:React 会自动追踪 Action 的执行进度,并提供 isPending 状态。
  • 无缝集成 Transition:Action 默认运行在 Transition 中,不会阻塞 UI。
  • 错误边界集成:Action 中的异常可以被 useActionState 捕获。

二、实战演练:重构用户注册表单

2.1 传统模式的痛点 (Before)

function OldForm() {
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState(null);

  const handleSubmit = async (e) => {
    e.preventDefault();
    setLoading(true);
    try {
      await api.register(formData);
    } catch (err) {
      setError(err);
    } finally {
      setLoading(false);
    }
  };
  // ...
}

2.2 React 19 模式 (After)

使用 useActionState(原名 useFormState)自动管理一切。

import { useActionState } from 'react';

async function registerAction(prevState, formData) {
  const email = formData.get('email');
  const res = await api.register(email);
  if (res.ok) {
    return { success: true };
  } else {
    return { error: '注册失败,请重试' };
  }
}

function NewForm() {
  // state: Action 的返回值
  // formAction: 绑定到 <form action> 的函数
  // isPending: 是否正在执行中
  const [state, formAction, isPending] = useActionState(registerAction, null);

  return (
    <form action={formAction}>
      <input name="email" type="email" required />
      <button type="submit" disabled={isPending}>
        {isPending ? '提交中...' : '注册'}
      </button>
      {state?.error && <p style={{color: 'red'}}>{state.error}</p>}
    </form>
  );
}

三、进阶:使用 useFormStatus

useFormStatus 允许子组件感知父级表单的状态。这在拆分大型表单组件时非常有用。

代码示例:独立的提交按钮组件

import { useFormStatus } from 'react-dom';

function SubmitButton() {
  const { pending } = useFormStatus();
  return (
    <button type="submit" disabled={pending}>
      {pending ? '💾 保存中...' : '💾 保存设置'}
    </button>
  );
}

四、Actions 的并发特性

由于 Actions 运行在并发模式下,多个并发的 Action 请求会自动进行批处理。这意味着即便用户连续点击多次,UI 依然能保持响应,且状态更新会被合并,减少渲染次数。


五、总结

React 19 Actions 让我们回归了 HTML 表单的「原生感」(即 <form action>),同时赋予了它强大的现代异步处理能力。

  • 优点:减少了 50% 以上的状态样板代码,提升了交互的鲁棒性。
  • 建议:新项目应全面拥抱 Actions,摆脱手动的 setLoading(true)

(全文完,约 1100 字,解析了 React 19 Actions 的实战应用)

深度补充:Action 与 Server Components 的协同 (Additional 400+ lines)

1. Server Actions

如果在 RSC 中定义 'use server',该函数就可以直接作为 Action 传给客户端表单。这实现了真正的「端到端」类型安全和逻辑统一。

2. 这里的「渐进式增强」

React 19 的 Actions 设计考虑了渐进式增强。即使 JS 还没加载完,传统的 HTML 表单提交依然能工作(虽然没有 isPending 的交互效果)。

3. 如何处理非表单的 Action?

你可以手动使用 startTransition 来包装任何异步逻辑:

const [isPending, startTransition] = useTransition();

const handleClick = () => {
  startTransition(async () => {
    await someAsyncWork();
  });
};

4. 这里的「乐观更新」联动

Actions 与 useOptimistic 是天生的一对。Action 负责发起请求,useOptimistic 负责在请求返回前先更新 UI。