useFormStatus

useFormStatus 是一个 Hook,用于提供上一次表单提交的状态信息。

const { pending, data, method, action } = useFormStatus();

参考

🌐 Reference

useFormStatus()

useFormStatus Hook 提供上一次表单提交的状态信息。

🌐 The useFormStatus Hook provides status information of the last form submission.

import { useFormStatus } from "react-dom";
import action from './actions';

function Submit() {
const status = useFormStatus();
return <button disabled={status.pending}>Submit</button>
}

export default function App() {
return (
<form action={action}>
<Submit />
</form>
);
}

要获取状态信息,Submit 组件必须在 <form> 中渲染。这个 Hook 会返回诸如 pending 属性的信息,该属性告诉你表单是否正在提交。

🌐 To get status information, the Submit component must be rendered within a <form>. The Hook returns information like the pending property which tells you if the form is actively submitting.

在上面的例子中,Submit 使用此信息在表单提交时禁用 <button> 按键。

🌐 In the above example, Submit uses this information to disable <button> presses while the form is submitting.

查看更多示例。

参数

🌐 Parameters

useFormStatus 不接受任何参数。

返回

🌐 Returns

具有以下属性的 status 对象:

🌐 A status object with the following properties:

  • pending:一个布尔值。如果是 true,这意味着父级 <form> 正在等待提交。否则,false
  • data:一个实现 FormData interface 的对象,包含父级 <form> 正在提交的数据。如果没有活动的提交或没有父级 <form>,它将是 null
  • method:一个字符串值,可以是 'get''post'。这表示父 <form> 是使用 GET 还是 POST HTTP 方法 提交。默认情况下,<form> 将使用 GET 方法,并且可以通过 method 属性指定。
  • action:对传递给父组件 <form>action 属性的函数的引用。如果没有父组件 <form>,该属性为 null。如果向 action 属性提供了 URI 值,或者未指定 action 属性,status.action 将是 null

注意事项

🌐 Caveats

  • useFormStatus Hook 必须从渲染在 <form> 内的组件中调用。
  • useFormStatus 只会返回父 <form> 的状态信息。它不会返回在同一组件或子组件中呈现的任何 <form> 的状态信息。

用法

🌐 Usage

表单提交期间显示待处理状态

🌐 Display a pending state during form submission

要在表单提交时显示待处理状态,你可以在渲染于 <form> 的组件中调用 useFormStatus Hook,并读取返回的 pending 属性。

🌐 To display a pending state while a form is submitting, you can call the useFormStatus Hook in a component rendered in a <form> and read the pending property returned.

在这里,我们使用 pending 属性来表示表单正在提交。

🌐 Here, we use the pending property to indicate the form is submitting.

import { useFormStatus } from "react-dom";
import { submitForm } from "./actions.js";

function Submit() {
  const { pending } = useFormStatus();
  return (
    <button type="submit" disabled={pending}>
      {pending ? "Submitting..." : "Submit"}
    </button>
  );
}

function Form({ action }) {
  return (
    <form action={action}>
      <Submit />
    </form>
  );
}

export default function App() {
  return <Form action={submitForm} />;
}

易犯错误

useFormStatus 不会返回在同一组件中渲染的 <form> 的状态信息。

🌐 useFormStatus will not return status information for a <form> rendered in the same component.

useFormStatus Hook 只返回父级 <form> 的状态信息,而不会返回在调用该 Hook 的同一组件中渲染的任何 <form> 或子组件的状态信息。

🌐 The useFormStatus Hook only returns status information for a parent <form> and not for any <form> rendered in the same component calling the Hook, or child components.

function Form() {
// 🚩 `pending` will never be true
// useFormStatus does not track the form rendered in this component
const { pending } = useFormStatus();
return <form action={submit}></form>;
}

改为从位于 <form> 内的组件中调用 useFormStatus

🌐 Instead call useFormStatus from inside a component that is located inside <form>.

function Submit() {
// ✅ `pending` will be derived from the form that wraps the Submit component
const { pending } = useFormStatus();
return <button disabled={pending}>...</button>;
}

function Form() {
// This is the <form> `useFormStatus` tracks
return (
<form action={submit}>
<Submit />
</form>
);
}

读取正在提交的表单数据

🌐 Read the form data being submitted

你可以使用从 useFormStatus 返回的状态信息的 data 属性来显示用户正在提交的数据。

🌐 You can use the data property of the status information returned from useFormStatus to display what data is being submitted by the user.

在这里,我们有一个表单,用户可以请求一个用户名。我们可以使用 useFormStatus 来显示一个临时状态消息,确认他们请求了哪个用户名。

🌐 Here, we have a form where users can request a username. We can use useFormStatus to display a temporary status message confirming what username they have requested.

import {useState, useMemo, useRef} from 'react';
import {useFormStatus} from 'react-dom';

export default function UsernameForm() {
  const {pending, data} = useFormStatus();

  return (
    <div>
      <h3>Request a Username: </h3>
      <input type="text" name="username" disabled={pending}/>
      <button type="submit" disabled={pending}>
        Submit
      </button>
      <br />
      <p>{data ? `Requesting ${data?.get("username")}...`: ''}</p>
    </div>
  );
}


故障排除

🌐 Troubleshooting

status.pending 永远不是 true

🌐 status.pending is never true

useFormStatus 只会返回父 <form> 的状态信息。

如果调用 useFormStatus 的组件没有嵌套在 <form> 中,status.pending 将始终返回 false。请验证 useFormStatus 是否在一个是 <form> 元素子组件中被调用。

🌐 If the component that calls useFormStatus is not nested in a <form>, status.pending will always return false. Verify useFormStatus is called in a component that is a child of a <form> element.

useFormStatus 不会跟踪在同一组件中渲染的 <form> 的状态。更多细节请参见 陷阱