useFormStatus - This feature is available in the latest Canary

useFormStatus 是一個 Hook,可以提供您最後一次表單提交的狀態資訊。

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

參考

useFormStatus()

useFormStatus Hook 提供最後一次表單提交的狀態資訊。

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 屬性,它會告訴您表單是否正在 actively 提交中。

在上面的例子中,Submit 使用這個資訊來停用表單提交期間的 <button> 按鈕。

請參閱下面的更多範例。

參數

useFormStatus 不需要任何參數。

回傳值

一個具有以下屬性的 status 物件

  • pending:一個布林值。如果為 true,表示父層 <form> 正在等待提交。否則為 false

  • data:一個實作 FormData 介面 的物件,其中包含父層 <form> 正在提交的資料。如果沒有 active 的提交或沒有父層 <form>,它將會是 null

  • method:字串值,可以是 'get''post'。這表示父層 <form> 正在使用 GETPOST HTTP 方法 提交。預設情況下,<form> 將使用 GET 方法,並且可以通過 method 屬性來指定。

  • action:參照父層 `<form>` 中 `action` prop 傳入的函式。如果沒有父層 `<form>`,則此屬性為 `null`。如果 `action` prop 提供了 URI 值,或者沒有指定 `action` prop,則 `status.action` 將會是 `null`。

注意事項

  • `useFormStatus` Hook 必須從渲染在 `<form>` 內部的元件呼叫。
  • `useFormStatus` 只會回傳父層 `<form>` 的狀態資訊。它不會回傳在同一個元件或子元件中渲染的任何 `<form>` 的狀態資訊。

用法 ...

在表單提交期間顯示處理中狀態 ...

要在表單提交時顯示處理中狀態,您可以在 `<form>` 中渲染的元件中呼叫 `useFormStatus` Hook,並讀取回傳的 `pending` 屬性。

這裡,我們使用 `pending` 屬性來指示表單正在提交。

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` Hook 只會回傳父層 `<form>` 的狀態資訊,而不會回傳在呼叫 Hook 的同一個元件或子元件中渲染的任何 `<form>` 的狀態資訊。

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`。

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>
);
}

讀取正在提交的表單資料 ...

您可以使用從 `useFormStatus` 回傳的狀態資訊的 `data` 屬性來顯示使用者正在提交的資料。

這裡,我們有一個使用者可以請求使用者名稱的表單。我們可以使用 `useFormStatus` 來顯示一個臨時狀態訊息,確認他們請求的使用者名稱。

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>
  );
}


疑難排解 ...

`status.pending` 永遠不會是 `true` ...

`useFormStatus` 只會回傳父層 `<form>` 的狀態資訊。

如果呼叫 useFormStatus 的組件沒有嵌套在 <form> 中,status.pending 將永遠返回 false。請確認 useFormStatus 是在 <form> 元素的子組件中呼叫的。

useFormStatus 不會追蹤在同一個組件中渲染的 <form> 的狀態。更多詳細資訊,請參閱陷阱