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>
. Хук повертає інформацію на зразок
У наведеному вище прикладі 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>
, що рендериться у тому самому компоненті. Дивіться Пастка для більш детальної інформації.