Валидация форм в современных фронтенд-приложениях строится вокруг событийной модели ввода данных, где ключевую роль играют моменты изменения значения поля и потеря фокуса. В связке с React Hook Form и схемной валидацией через Yup особое значение приобретает выбор стратегии запуска проверки: onChange и onBlur определяют баланс между отзывчивостью интерфейса и нагрузкой на систему валидации.
Событие onChange возникает при каждом изменении значения
поля ввода. Это делает его максимально чувствительным механизмом,
позволяющим реагировать на ввод в реальном времени. Однако такая
чувствительность приводит к потенциальной избыточности: каждая клавиша
инициирует цепочку обновлений состояния и повторную валидацию.
Событие onBlur срабатывает при потере фокуса элементом
формы. В отличие от onChange, оно агрегирует изменения,
откладывая проверку до завершения ввода. Это снижает количество вызовов
валидатора и уменьшает визуальный шум ошибок, но увеличивает задержку
обратной связи.
В рамках сложных форм выбор между этими стратегиями влияет на UX, производительность и стабильность состояния ошибок.
React Hook Form использует неконтролируемую модель форм с минимальным количеством перерендеров. Это делает его особенно чувствительным к частоте триггеров валидации.
Интеграция со схемами валидации реализуется через слой адаптации — resolver. В экосистеме используется пакет @hookform/resolvers, который связывает внешние схемы (например, Yup) с внутренним механизмом проверки RHF.
Роль resolver заключается в следующем:
Таким образом, Yup не используется напрямую внутри компонентов формы, а выступает как декларативный слой описания правил.
Yup предоставляет объектную модель описания данных, где каждое поле сопровождается цепочкой правил:
Пример схемы:
import * as Yup from "yup";
const schema = Yup.object({
email: Yup.string()
.email("Некорректный формат")
.required("Поле обязательно"),
password: Yup.string()
.min(8, "Минимум 8 символов")
.required("Поле обязательно"),
});
Эта схема не зависит от UI-слоя и может использоваться в различных контекстах: клиентская валидация, серверная проверка, тестирование.
@hookform/resolvers обеспечивает адаптацию Yup-схемы для React Hook Form.
Механизм работы включает:
получение текущих значений формы
передача их в Yup-схему
выполнение синхронной или асинхронной валидации
преобразование ошибок Yup в формат RHF:
{
fieldName: {
type: "validationType",
message: "Ошибка"
}
}возврат результата в React Hook Form
Этот слой абстракции позволяет не писать ручную валидацию и не синхронизировать правила между UI и бизнес-логикой.
React Hook Form поддерживает несколько режимов валидации, которые напрямую влияют на момент вызова resolver.
Режим onChange активирует проверку при каждом изменении
значения поля.
Характерные особенности:
Применяется в случаях, где критична моментальная проверка корректности, например:
Пример конфигурации:
const form = useForm({
resolver: yupResolver(schema),
mode: "onChange",
});
Режим onBlur запускает проверку только при потере фокуса
поля.
Особенности:
Пример:
const form = useForm({
resolver: yupResolver(schema),
mode: "onBlur",
});
Данный режим особенно эффективен для длинных форм, где каждое поле имеет сложные правила.
Часто используется комбинация поведения:
В React Hook Form это достигается через конфигурацию:
const form = useForm({
resolver: yupResolver(schema),
mode: "onBlur",
reValidateMode: "onChange",
});
Здесь:
mode задаёт первичный триггерreValidateMode определяет поведение после появления
ошибкиКаждый триггер (onChange или onBlur) запускает следующий цикл:
При onChange этот цикл повторяется многократно в
короткие интервалы времени, что делает оптимизацию критически
важной.
Использование Yup в связке с частыми событиями требует учёта стоимости валидации.
Факторы нагрузки:
test функцииtransform)При режиме onChange важно учитывать:
shouldUnregister: false для стабильности
состоянияВ режиме onBlur основная нагрузка переносится на редкие,
но более крупные вызовы, что делает поведение более предсказуемым.
Yup возвращает структурированные ошибки, которые затем нормализуются resolver’ом.
При onChange ошибки могут появляться и исчезать
динамически, что требует аккуратного UI-представления:
При onBlur ошибки фиксируются после завершения ввода,
что упрощает визуальную модель состояния формы.
В реальных приложениях часто используется смешанный подход:
Также встречаются сценарии ручного управления:
trigger("fieldName");
Этот метод позволяет принудительно запускать resolver вне стандартного жизненного цикла событий.
Распространённые проблемы:
Особенно критично сочетание сложного
Yup.object().shape() с режимом onChange без мемоизации.
Yup поддерживает асинхронные проверки через test, что
влияет на поведение onChange:
Формы делятся на:
Для простых форм допустим onChange без ограничений.
Для сложных форм предпочтительнее:
Взаимодействие onBlur и onChange в связке с resolver-архитектурой формирует основу предсказуемой и масштабируемой модели валидации, где Yup выступает декларативным источником правил, React Hook Form управляет состоянием, а @hookform/resolvers связывает оба слоя в единую систему исполнения.