以前写一个提交表单,要自己管理“提交中”“错误信息”“成功后清空”几个状态。React 19 把这套流程收进了 Actions:<form> 的 action 可以直接传一个函数,提交中的状态和返回结果由 React 管理。
TypeScript
import { useActionState } from "react";
async function subscribe(_previous: string | null, formData: FormData) {
const email = String(formData.get("email") ?? "");
if (!email.includes("@")) return "邮箱格式不对";
const response = await fetch("/api/subscribe", {
method: "POST",
body: formData,
});
return response.ok ? null : "订阅失败,请稍后再试";
}
export function SubscribeForm() {
const [error, formAction, isPending] = useActionState(subscribe, null);
return (
<form action={formAction}>
<input name="email" type="email" required />
<button disabled={isPending}>{isPending ? "提交中…" : "订阅"}</button>
{error && <p role="alert">{error}</p>}
</form>
);
}要点
useActionState(action, 初始值)返回三项:上一次 action 的返回值、包装后的 action、是否正在进行。- action 的第一个参数是上一次的返回值,第二个参数才是
FormData,顺序别写反。 - 提交按钮放在单独的组件里时,用
react-dom的useFormStatus()读取所在表单的提交状态,不用再从上层传 props。 useOptimistic适合点赞、发评论这类场景:先显示结果,请求失败再回滚。- action 成功完成后,React 会重置表单里的非受控字段;需要保留输入时,把字段改成受控组件。