useFormStatus

Хук useFormStatus наразі доступний лише в Canary та експериментальних каналах React. Дізнайтеся більше про канали релізів React тут.

useFormStatus - хук, який надає вам інформацію про стан останнього відправлення форми.

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

Довідник

useFormStatus()

Хук useFormStatus надає інформацію про статус останнього відправлення форми.

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>. Хук повертає інформацію на зразок <code>pending Властивість, яка показує, чи форма активно надсилається.

У наведеному вище прикладі Submit використовує цю інформацію, щоб вимкнути натискання <button> під час надсилання форми.

Дивіться більше прикладів нижче.

Параметри

useFormStatus не приймає жодних параметрів.

Повертає

Об'єкт status з такими властивостями:

  • pending: Булевий вираз. Якщо true, це означає, що батько <form> очікує на передачу. В іншому разі - false.

  • data: Об'єкт, що реалізує FormData interface, який містить дані, які надсилає батьківський <form>. Якщо немає активного подання або немає батька <form>, він буде null.

  • method: Рядкове значення або 'get', або 'post'. Це показує, чи надсилає батьківський <form> за допомогою GET або POST HTTP-методу. За замовчуванням <form> використовуватиме метод GET, який можна вказати за допомогою властивості method.

  • action: Посилання на функцію, передану в проп action у батьківському <form>. Якщо батька <form> не існує, властивість має значення null. Якщо до властивості action надано значення URI або не вказано жодної властивості action, status.action буде null.

Застереження

  • Хук useFormStatus має бути викликаний з компонента, який рендериться всередині <form>.
  • useFormStatus поверне інформацію про стан лише для батька <form>. Він не поверне інформацію про стан для будь-якого <form>, відрендереного у цьому ж компоненті або дочірніх компонентах.

Використання

Показувати стан очікування під час надсилання форми

Щоб відобразити стан очікування під час надсилання форми, ви можете викликати хук useFormStatus у компоненті, відрендереному у <form>, і прочитати повернуту властивість 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} />;
}
export async function submitForm(query) {
    await new Promise((res) => setTimeout(res, 1000));
}
{
  "dependencies": {
    "react": "canary",
    "react-dom": "canary",
    "react-scripts": "^5.0.0"
  },
  "main": "/index.js",
  "devDependencies": {}
}
useFormStatus не повертатиме інформацію про стан для <form>, відрендереного у тому ж компоненті.

Хук useFormStatus повертає інформацію про стан лише для батьківського <form>, а не для будь-якого <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>;
}

Замість цього викликайте useFormStatus зсередини компонента, який знаходиться всередині <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>
  );
}

прочитати дані форми, що надсилаються

Ви можете використати властивість data інформації про стан, повернутої з useFormStatus, щоб показати, які дані надсилає користувач.

Тут ми маємо форму, за допомогою якої користувачі можуть запитувати ім'я користувача. Ми можемо використати useFormStatus для відображення тимчасового повідомлення про стан, яке підтверджує, яке ім'я користувача було запитано.

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

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

  const [showSubmitted, setShowSubmitted] = useState(false);
  const submittedUsername = useRef(null);
  const timeoutId = useRef(null);

  useMemo(() => {
    if (pending) {
      submittedUsername.current = data?.get('username');
      if (timeoutId.current != null) {
        clearTimeout(timeoutId.current);
      }

      timeoutId.current = setTimeout(() => {
        timeoutId.current = null;
        setShowSubmitted(false);
      }, 2000);
      setShowSubmitted(true);
    }
  }, [pending, data]);

  return (
    <>
      <label>Request a Username: </label><br />
      <input type="text" name="username" />
      <button type="submit" disabled={pending}>
        {pending ? 'Submitting...' : 'Submit'}
      </button>
      {showSubmitted ? (
        <p>Submitted request for username: {submittedUsername.current}</p>
      ) : null}
    </>
  );
}
import UsernameForm from './UsernameForm';
import { submitForm } from "./actions.js";

export default function App() {
  return (
    <form action={submitForm}>
      <UsernameForm />
    </form>
  );
}
export async function submitForm(query) {
    await new Promise((res) => setTimeout(res, 1000));
}
{
  "dependencies": {
    "react": "canary",
    "react-dom": "canary",
    "react-scripts": "^5.0.0"
  },
  "main": "/index.js",
  "devDependencies": {}
}

Вирішення проблем

status.pending ніколи не є істинним

useFormStatus повертатиме інформацію про стан лише для батьківського <form>.

Якщо компонент, який викликає useFormStatus, не вкладено у <form>, status.pending завжди повертатиме false. Перевірка useFormStatus викликається у компоненті, який є нащадком елемента <form>.

useFormStatus не відстежуватиме стан <form>, що рендериться у тому самому компоненті. Дивіться Пастка для більш детальної інформації.