Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Як показати стан відправки форми на кнопці через useFormStatus і чому він інколи завжди false?

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 і текстова зміна на кнопці, щоб стан відправки був зрозумілий не лише візуально.

Докладніше в документації: useFormStatus

Схожі питання