React useFormStatus获取父级form提交状态
useFormStatus 是 React 18 引入的一个 Hook,用于在表单的子组件中获取父级 <form> 的提交状态。它解决了在表单提交过程中,如何控制子组件(如提交按钮)UI 变化的常见问题,例如将“提交”按钮变为“提交中...”并禁用,或者在提交成功后显示提示信息。
基本用法
useFormStatus 必须在 <form> 组件的子组件中使用,并且该子组件必须是 action 属性的直接或间接子节点。它返回一个包含提交状态信息的对象。
-
创建一个表单组件: 首先,你需要一个带有
action属性的<form>组件。action属性可以是一个函数,用于处理表单提交。 -
在子组件中调用
useFormStatus: 在表单的子组件(通常是提交按钮)中,调用useFormStatusHook。 -
使用返回的状态: Hook 返回一个对象,包含以下属性:
| 属性 | 类型 | 描述 |
|---|---|---|
pending |
boolean |
表示表单是否正在提交。 |
data |
FormData |
包含提交表单数据的 FormData 对象。 |
method |
string |
表单提交的方法,如 GET 或 POST。 |
action |
string |
表单的 action 属性值。 |
实战示例:控制提交按钮状态
最常见的使用场景是控制提交按钮的显示文本和禁用状态。
-
构建一个表单: 创建一个包含输入框和提交按钮的表单。
-
在提交按钮中使用
useFormStatus: 在<button type="submit">组件内部,调用useFormStatus并解构出pending状态。 -
根据
pending状态动态渲染: 使用pending布尔值来决定按钮的文本和disabled属性。
import { useFormStatus } from 'react-dom';
function SubmitButton() {
const { pending } = useFormStatus();
return (
<button type="submit" disabled={pending}>
{pending ? '提交中...' : '提交'}
</button>
);
}
function MyForm() {
async function handleSubmit(formData) {
// 模拟网络请求
await new Promise(resolve => setTimeout(resolve, 2000));
console.log('提交的数据:', Object.fromEntries(formData));
}
return (
<form action={handleSubmit}>
<input type="text" name="username" placeholder="请输入用户名" />
<SubmitButton />
</form>
);
}
在上述代码中,当用户点击“提交”按钮时,useFormStatus 会检测到表单正在提交,pending 变为 true,按钮文本变为“提交中...”并禁用,防止用户重复点击。提交完成后,pending 恢复为 false,按钮恢复原状。
处理提交结果
useFormStatus 返回的 data 属性包含了提交的表单数据,你可以在提交完成后使用它来显示成功信息或进行其他操作。
-
获取提交数据: 在提交按钮组件中,除了
pending,你还可以获取data。 -
在提交完成后使用数据: 当
pending为false时,data中将包含完整的提交数据。
import { useFormStatus } from 'react-dom';
function SubmitButton() {
const { pending, data } = useFormStatus();
return (
<button type="submit" disabled={pending}>
{pending ? '提交中...' : '提交'}
</button>
);
}
function SuccessMessage() {
const { data, pending } = useFormStatus();
if (!pending && data) {
const username = data.get('username');
return <p>欢迎, {username}! 提交成功。</p>;
}
return null;
}
function MyForm() {
async function handleSubmit(formData) {
await new Promise(resolve => setTimeout(resolve, 2000));
}
return (
<form action={handleSubmit}>
<input type="text" name="username" placeholder="请输入用户名" />
<SubmitButton />
<SuccessMessage />
</form>
);
}
在这个例子中,我们创建了一个 SuccessMessage 组件,它也使用了 useFormStatus。当提交完成(pending 为 false)并且 data 存在时,它会从 data 中获取 username 并显示成功信息。
重要注意事项
-
使用位置限制:
useFormStatus必须 在<form>组件的内部使用,并且是action属性的子组件。它不能在<form>外部使用,也不能在没有action属性的表单中使用。 -
与
onSubmit的区别:useFormStatus主要用于管理表单提交的 UI 状态(如按钮禁用),而onSubmit是一个传统的事件处理函数,用于执行提交逻辑。在 React 18 及以上版本中,推荐使用action属性来处理表单提交,useFormStatus则是与之配合使用的 UI 状态管理工具。 -
pending状态的触发:pending状态在表单开始提交时(即action函数被调用时)变为true,并在提交完成(无论是成功还是失败)后变为false。

暂无评论,快来抢沙发吧!