useFormStatus (з react-dom) повертає стан відправки батьківської форми: pending, data (FormData, що відправляється), method, action.
import { useFormStatus } from 'react-dom';
function SubmitButton({ children }) {
const { pending } = useFormStatus();
return (
<button type="submit" disabled={pending} aria-busy={pending}>
{pending ? 'Зберігаємо...' : children}
</button>
);
}
function ProfileForm() {
return (
<form action={updateProfile}>
<input name="name" />
<SubmitButton>Зберегти</SubmitButton>
</form>
);
}
Кнопку з власним станом можна використовувати в будь-якій формі - без передачі isSubmitting через props.
Чому pending завжди false. Хук бачить лише форму, всередині якої рендериться компонент. Якщо викликати його в тому самому компоненті, що рендерить <form>, батьківської форми для хука немає:
function ProfileForm() {
const { pending } = useFormStatus(); // завжди false: форма нижче, а не вище
return <form action={updateProfile}>...</form>;
}
Тому стан відправки виносять в окремий дочірній компонент (кнопка, індикатор), а в компоненті з формою для цього є isPending з useActionState.
Інші умови роботи:
- форма має відправлятися через дію (
action={функція}). ЗonSubmitчиaction="/url"хук нічого не знає про відправку; - поле
dataдає змогу показати, що саме відправляється («Додаємо "Купити молоко"...»).
Навіщо блокувати кнопку на час відправки: від подвійних відправок (два замовлення, два коментарі). Але це UX-захист - сервер теж має бути готовим до повторів (ключі ідемпотентності, унікальні обмеження).
Доступність: aria-busy і текстова зміна на кнопці, щоб стан відправки був зрозумілий не лише візуально.