跳到主要内容

表单提交状态

useFormStatus 读取哪一个表单?​

  • 最近祖先: 在 form 内的子组件调用 useFormStatus,读取最近父表单的提交状态,而不是组件自己返回的 form;
  • 必须下移: 如果 Hook 与 form 标签在同一组件函数里,Hook 不会读取那个尚未成为祖先的标签,需提取 SubmitButton 等子组件;
  • 角色区别: 此 Hook 观察表单状态,不管理操作返回值,结果状态由 useActionState 等负责;
import { useFormStatus } from "react-dom";

function SubmitButton() {
const { pending } = useFormStatus();
return <button disabled={pending}>{pending ? "正在提交" : "提交"}</button>;
}

function Form({ submit }) {
return (
<form action={submit}>
<input name="message" />
<SubmitButton />
</form>
);
}

返回对象中的字段分别代表什么?​

字段含义
pending父表单是否正在提交
data本次提交的 FormData,无提交时为 null
method本次提交采用的 get 或 post
action传入的函数 action;URL action 或无对应提交时可为 null

如何在提交期间展示用户正在提交的内容?​

  • 提交快照: 从 data.get('字段名') 读取这一次提交数据,可以与用户随后修改的输入值区分;
  • 空值处理: 尚未提交时 data 为 null,读取前使用可选链或条件判断;
  • 范围限制: 不会追踪另一个兄弟 form,也不会因为任意点击处理器里发了 fetch 就变成 pending;
function SubmissionPreview() {
const { pending, data } = useFormStatus();
if (!pending) return null;
const message = String(data?.get("message") ?? "");
return <p aria-live="polite">正在发送:{message}</p>;
}
  • 放置位置: 将 SubmissionPreview 放在提交 message 字段的 form 内,它显示提交快照,而非另一份独立输入状态;