Содержание
Коротко
Классическая схема форм — Pydantic на бэкенде, Zod на фронте, ручные useState и useTransition. Автор CitizenApp показывает связку React 19 Form Actions с FastAPI: правила валидации живут один раз на сервере, клиент получает структурированные ошибки через useActionState.
Что произошло
«Старый путь» держит логику формы в пяти местах: схема Pydantic, дубликат в Zod, REST-эндпоинт, ручные сообщения об ошибках, колбэки отправки. Новое правило валидации — правки минимум в трёх файлах; если клиент прошёл, а сервер отклонил — пользователь видит спиннер и общую ошибку.
Паттерн: форма отправляется в server action (функция с 'use server'), action вызывает FastAPI, FastAPI валидирует тело через Pydantic и возвращает 422 с деталями или успешный ответ. useActionState даёт [state, formAction, isPending] — состояние загрузки и ошибки по полям без отдельных хуков.
Схема на сервере — единственный источник правды. TypeScript-типы можно генерировать из Pydantic (datamodel-code-generator). В JSX ошибки фильтруются по field и показываются рядом с инпутами.
Почему это важно
Дублирование валидации — один из главных источников багов в full-stack приложениях. Серверная проверка обязательна (клиент обходится), но клиентская «для UX» часто расходится с бэкендом. Централизация на Pydantic убирает рассинхрон.
Server action как мост скрывает FastAPI от браузера: чувствительные операции не попадают в клиентский код. isPending блокирует кнопку без useState. Автор оценивает сокращение кода форм примерно вдвое.
Подводный камень: формат 422 от FastAPI — массив detail с loc (кортеж, имя поля на индексе 1) и msg. Трансформацию в { field, message } нужно написать один раз осознанно.
На практике
- Определите Pydantic-модель запроса и ответа с
errors: list[ValidationError]. - Server action собирает
FormData, шлёт JSON на FastAPI, мапит 422 в ваш формат. - Подключите
useActionState(action, null)— не дублируйте loading state. - Рендерите ошибки по
state.errors.filter(e => e.field === 'email'). - Сгенерируйте TS-типы из Python-схем, не копируйте вручную.
- Кастомные сообщения — через
Field(description=...)в Pydantic.
Итог
React 19 Form Actions + FastAPI — практичный выход из ада «две схемы, два набора сообщений». Не замена клиентской валидации для мгновенного UX, но надёжная основа для отправки. Пошаговый код — в оригинале на Dev.to.