Skip to main content

Що таке useFormStatus?

Що таке useFormStatus()

useFormStatus() - це React-хук, який надає поточний стан форми, пов'язаної з Action. Він повідомляє, чи виконується сабміт (pending), які дані відправлені (data), чи є помилка (error) тощо.

Простіше кажучи: useFormStatus() дає вам доступ до стану самої форми, аналогічно тому, як useActionState() керує станом Action.


Синтаксис

javascript
const { pending, data, method, action } = useFormStatus();
ПолеОпис
pendingtrue, поки форма виконує Action (аналог isSubmitting)
dataОб'єкт FormData з відправленими даними
methodМетод форми (GET, POST тощо)
actionПосилання на Action-функцію, прикріплену до форми

Як це працює

React 19 тепер розуміє <form> як керований елемент:

  • При сабміті React автоматично викликає Action (серверну чи клієнтську);
  • Поки Action виконується, React оновлює useFormStatus() всередині цієї форми;
  • Компоненти, вкладені у форму, можуть читати цей стан і показувати, наприклад, спінер або повідомлення про помилку.

Приклад: індикатор завантаження форми

javascript
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>

Хук отримує контекст форми від найближчого батька:

javascript
function MyButton() { const { pending } = useFormStatus(); // працює тільки якщо всередині <form> ... }

Якщо викликати його поза <form>, він поверне "порожній" стан (pending = false тощо).


2. Працює із Server Actions та Client Actions

javascript
<form action={myServerAction}> ... </form>

або

javascript
const [state, formAction] = useActionState(myClientAction, initial); <form action={formAction}>...</form>

В обох випадках useFormStatus() відстежує статус виконання цієї Action.


3. Дозволяє створювати переюзабельні компоненти кнопок та індикаторів

Наприклад:

javascript
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() керує візуальним станом форми.


Приклад комбінації

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

Більш просунутий приклад (компоненти окремо)

javascript
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().

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.