Що таке useFormStatus?
Що таке useFormStatus()
useFormStatus()- це React-хук, який надає поточний стан форми, пов'язаної з Action. Він повідомляє, чи виконується сабміт (pending), які дані відправлені (data), чи є помилка (error) тощо.
Простіше кажучи:
useFormStatus() дає вам доступ до стану самої форми,
аналогічно тому, як useActionState() керує станом Action.
Синтаксис
const { pending, data, method, action } = useFormStatus();| Поле | Опис |
|---|---|
pending | true, поки форма виконує Action (аналог isSubmitting) |
data | Об'єкт FormData з відправленими даними |
method | Метод форми (GET, POST тощо) |
action | Посилання на Action-функцію, прикріплену до форми |
Як це працює
React 19 тепер розуміє <form> як керований елемент:
- При сабміті React автоматично викликає Action (серверну чи клієнтську);
- Поки Action виконується, React оновлює
useFormStatus()всередині цієї форми; - Компоненти, вкладені у форму, можуть читати цей стан і показувати, наприклад, спінер або повідомлення про помилку.
Приклад: індикатор завантаження форми
import { useActionState, useFormStatus } from 'react';
async function sendMessage(prev, formData) {
const message = formData.get('message');
await api.send(message);
return { success: true };
}
function SubmitButton() {
const { pending } = useFormStatus();
return (
<button type="submit" disabled={pending}>
{pending ? 'Sending...' : 'Send'}
</button>
);
}
export default function ChatForm() {
const [state, formAction] = useActionState(sendMessage, null);
return (
<form action={formAction}>
<input name="message" />
<SubmitButton />
{state?.success && <p>Message sent!</p>}
</form>
);
}Тут:
useFormStatus()працює всерединіSubmitButton, але автоматично знає, що він належить формі, де вказаноaction={formAction};pendingстаєtrueпри сабміті, і React оновлює кнопку;- усе без ручного
useStateіsetLoading.
Особливості useFormStatus
1. Працює тільки всередині нащадків <form>
Хук отримує контекст форми від найближчого батька:
function MyButton() {
const { pending } = useFormStatus(); // працює тільки якщо всередині <form>
...
}Якщо викликати його поза <form>, він поверне "порожній" стан (pending = false тощо).
2. Працює із Server Actions та Client Actions
<form action={myServerAction}>
...
</form>або
const [state, formAction] = useActionState(myClientAction, initial);
<form action={formAction}>...</form>В обох випадках useFormStatus() відстежує статус виконання цієї Action.
3. Дозволяє створювати переюзабельні компоненти кнопок та індикаторів
Наприклад:
function SubmitButton({ children }) {
const { pending } = useFormStatus();
return (
<button disabled={pending}>
{pending ? 'Loading...' : children}
</button>
);
}Тепер таку кнопку можна використовувати у всіх формах без додаткової логіки.
4. Підтримує оптимістичні UI-патерни
Можна показувати тимчасові стани (наприклад, очищати поля, додавати "відправлене повідомлення"), поки Action виконується.
5. Працює з будь-якими методами форми (GET, POST тощо)
React передає в useFormStatus() method і data,
щоб за потреби можна було використовувати їх в UI.
Відмінність від useActionState()
| Хук | Де використовується | Що дає |
|---|---|---|
useActionState() | У компоненті, де оголошена Action | Керує станом Action (помилки, результат, pending) |
useFormStatus() | Всередині нащадків <form> | Дає статус самої форми (pending, data, method) |
| Типова роль | Логіка сабміту й оновлення даних | Відображення стану (кнопки, індикатори, поля) |
Часто вони працюють у парі:
useActionState() керує дією,
а useFormStatus() керує візуальним станом форми.
Приклад комбінації
async function updateEmail(prev, formData) {
const email = formData.get('email');
await api.updateEmail(email);
return { success: true };
}
function EmailForm() {
const [state, formAction] = useActionState(updateEmail, null);
const { pending } = useFormStatus();
return (
<form action={formAction}>
<input name="email" />
<button disabled={pending}>
{pending ? 'Saving...' : 'Save'}
</button>
{state?.success && <p>Email updated!</p>}
</form>
);
}Більш просунутий приклад (компоненти окремо)
function FormField({ label, name }) {
const { pending } = useFormStatus();
return (
<div className={pending ? 'disabled' : ''}>
<label>{label}</label>
<input name={name} disabled={pending} />
</div>
);
}
function SaveButton() {
const { pending } = useFormStatus();
return (
<button disabled={pending}>
{pending ? 'Saving...' : 'Save'}
</button>
);
}
function SettingsForm() {
const [state, formAction] = useActionState(saveSettings, null);
return (
<form action={formAction}>
<FormField label="Username" name="username" />
<FormField label="Email" name="email" />
<SaveButton />
{state?.success && <p>Saved!</p>}
</form>
);
}Усі поля й кнопка автоматично знають, що форма виконується, без пропів, контексту й isLoading.
Підсумок
useFormStatus()- це новий хук React 19, який дозволяє будь-якому компоненту всередині<form>знати, що форма виконує асинхронну дію, і реагувати на це.
Ключові переваги:
- Без ручного стану
isLoadingчиuseState; - Працює як із клієнтськими, так і з серверними Actions;
- Спрощує написання кнопок, спінерів, disabled-логіки;
- Дозволяє створювати універсальні переюзабельні форми;
- Глибоко інтегрований з
useActionState().
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.