Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Що таке useFormStatus?». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**`useFormStatus()`** - це React-хук, який надає поточний стан форми, пов'язаної з Action: чи виконується сабміт (`pending`), які дані відправлені (`data`), яким методом (`method`) і яка Action-функція прикріплена (`action`). **Ключове:** хук працює тільки всередині нащадків `<form>` і дає змогу створювати переюзабельні компоненти кнопок та індикаторів без ручного `useState`/`isLoading`.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення## Що таке `useFormStatus()` > `useFormStatus()` - це React-хук, який надає **поточний стан форми**, пов'язаної з **Action**. > Він повідомляє, чи виконується сабміт (`pending`), які дані відправлені (`data`), чи є помилка (`error`) тощо. Простіше кажучи: `useFormStatus()` дає вам **доступ до стану самої форми**, аналогічно тому, як `useActionState()` керує станом Action. --- ## Синтаксис ```javascript 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()` всередині цієї форми; - Компоненти, вкладені у форму, можуть читати цей стан і показувати, наприклад, спінер або повідомлення про помилку. --- ## Приклад: індикатор завантаження форми ```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()`.Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.