React 19: useActionState с Server Actions для форм и валидации
-

В React 19 хук useActionState вместе с Server Actions сильно упрощает работу с формами. Теперь не нужно вручную управлять состояниями загрузки, ошибками и валидацией - React берет это на себя. Это решает проблемы с boilerplate-кодом и делает формы быстрее и надежнее.
Зачем это нужно? Формы часто требуют обработки ошибок, индикации загрузки и серверной логики. Раньше приходилось писать кучу useState и useEffect. С useActionState все это сводится к одному хуку, который работает даже без JavaScript на клиенте. Получается прогрессивное улучшение и меньше кода.
Что такое useActionState и Server Actions
useActionState - это хук, который управляет состоянием формы при использовании Server Actions. Server Actions - это функции, помеченные как ‘use server’, которые выполняются на сервере напрямую из формы. Хук возвращает текущее состояние, функцию для диспатча действия и флаг isPending.
Представьте форму логина. Раньше вы писали onSubmit с fetch, setError и setLoading. Теперь форма просто ссылается на серверную функцию через action, а useActionState ловит ответ и обновляет UI. Это работает с FormData автоматически, без ручной синхронизации input’ов. Плюс, состояние приходит до гидратации, что ускоряет рендер.
Ключевые преимущества:
- Автоматическая обработка pending состояния без лишних хуков.
- Ошибки и успех возвращаются прямо в state.
- Поддержка прогрессивного улучшения - форма работает без JS.
- Интеграция с useOptimistic для мгновенного UI-обновления.
Сравнение подходов Аспект Классический useState useActionState Состояния Несколько useState (loading, error, data) Один хук Отправка onSubmit + fetch action={formAction} Ошибки setError вручную Автоматически из state Загрузка setLoading(true/false) isPending из хука Код Много boilerplate Минималистично Практический пример формы с валидацией
Давайте разберем форму логина на Next.js или Remix. Серверная функция проверяет email и пароль, возвращает ошибку или успех. useActionState принимает начальное состояние и обновляет его после действия. Форма использует uncontrolled inputs - браузер сам собирает FormData.
Код сервера:
'use server'; export async function loginAction(prevState, formData) { const email = formData.get('email'); const password = formData.get('password'); // Симуляция задержки await new Promise(r => setTimeout(r, 1000)); if (email === 'admin@example.com' && password === 'password') { return { success: true }; } return { success: false, error: 'Неверные данные' }; }На клиенте хук интегрируется просто. State содержит ошибки или сообщение успеха. isPending показывает спиннер. Валидация происходит на сервере, но можно добавить клиентскую с Zod или аналогами.
Шаги реализации:
- Импортируйте
useActionStateиз ‘react’. - Создайте
[state, formAction, isPending] = useActionState(loginAction, { error: null }). - В форме:
<form action={formAction}>с input’ами name=“email”. - Отобразите
{state.error && <p>{state.error}</p>}и{isPending && 'Загрузка...'}.
Важно: Используйте uncontrolled inputs - не связывайте value с useState для каждого поля.
Интеграция валидации и оптимистичные обновления
Для полной валидации комбинируйте с Zod на сервере. Server Action парсит схему, возвращает ошибки в state. useActionState обновляет форму с конкретными ошибками по полям. Это лучше, чем react-hook-form, - меньше зависимостей.
Пример с оптимистикой: корзина товаров. useOptimistic показывает +1 сразу, Server Action подтверждает на сервере. useActionState диспатчит, а optimistic дает отзывчивость. Отмена через AbortController для queued actions.
Возможности расширения:
- Валидация:
const result = schema.safeParse(formData); if (!result.success) return result.error. - Оптимистика:
const [optimisticState, addOptimistic] = useOptimistic(state). - Списки ошибок: State как
{ errors: { email: 'Ошибка' } }. - Множественные формы: useFormStatus для дочерних компонентов.
useActionState vs react-hook-form Фича useActionState react-hook-form Зависимости Нет Библиотека Server Actions Нативно Через onSubmit Авто-pending Да Ручная настройка Валидация Сервер + клиент Только клиент Код 20 строк 50+ строк Готовые решения для сложных форм
useActionState идеален для CRUD. В админке: форма создания поста с серверной валидацией изображений и текста. State возвращает preview или ошибки. Комбинируйте с useFormStatus для кнопок в дочерних компонентах - они знают о pending родителя.
Пример корзины:
import { useActionState, useOptimistic } from 'react'; const [count, dispatchAction, isPending] = useActionState(updateCart, 0); const [optimisticCount, setOptimistic] = useOptimistic(count); // В кнопках: setOptimistic(c => c + 1) перед dispatch.Плюсы для production:
- Меньше состояний - один хук вместо кучи.
- PWA-поддержка - работает оффлайн с service worker.
- Масштабируемость для больших форм с вложенными полями.
Масштабирование форм в реальных проектах
В крупных приложениях useActionState заменяет API-роуты. Next.js 15 компилирует actions в endpoints автоматически. Для TypeScript типизируйте state:
type State = { error?: string }. Тестируйте actions отдельно как функции.Ограничения: Пока нет нативной клиентской валидации - добавляйте trigger на onSubmit. Для сложных схем используйте библиотеки, но интегрируйте в action. Будущие обновления добавят useFormState (переименовано).
Это дает чистый код и скорость. Дальше можно углубиться в useFormStatus для контекста или комбо с TanStack Query для кэша.
Здравствуйте! Похоже, вас заинтересовала эта беседа, но у вас ещё нет аккаунта.
Надоело каждый раз пролистывать одни и те же посты? Зарегистрировав аккаунт, вы всегда будете возвращаться на ту же страницу, где были раньше, и сможете выбирать, получать ли уведомления о новых ответах (по электронной почте или в виде push-уведомлений). Вы также сможете сохранять закладки и ставить лайки постам, чтобы выразить свою благодарность другим участникам сообщества.
С вашими комментариями этот пост мог бы стать ещё лучше 💗
Зарегистрироваться Войти© 2024 - 2026 ExLends, Inc. Все права защищены.