React Hook Form — библиотека для форм, которая уменьшает количество state и обработчиков. Она особенно удобна для форм с валидацией, ошибками и отправкой данных.
- Базовая форма на React Hook Form
- Установка
- Минимальная форма
- Валидация
- Значения по умолчанию
- Когда React Hook Form особенно полезен
- Controller для UI-компонентов
- Практический пример: регистрация
- Что не стоит делать
- Следующий уровень
- Как понять, что форма написана нормально
- Проверочный список
- Когда подключать схемы валидации
- Что улучшить после первого варианта
- Что изучить дальше по React
Базовая форма на React Hook Form
Начинать лучше с простой формы: регистрация полей, валидация и значения по умолчанию. Когда этот слой понятен, Controller, схемы валидации и отправка на backend воспринимаются как развитие идеи, а не как отдельная магия.
Важная мысль: библиотека не отменяет понимание формы, а забирает на себя рутинную регистрацию полей и ошибки. Пользовательский сценарий всё равно нужно проектировать вручную.
Установка
npm install react-hook-form
Минимальная форма
import { useForm } from 'react-hook-form';
function ContactForm() {
const { register, handleSubmit } = useForm();
function onSubmit(data) {
console.log(data);
}
return (
<form onSubmit={handleSubmit(onSubmit)}>
<input {...register('name')} placeholder="Имя" />
<input {...register('email')} placeholder="Email" />
<button>Отправить</button>
</form>
);
}
register связывает input с формой. handleSubmit отменяет стандартную отправку, собирает данные и вызывает вашу функцию.
Валидация
function ContactForm() {
const {
register,
handleSubmit,
formState: { errors },
} = useForm();
return (
<form onSubmit={handleSubmit(console.log)}>
<input
{...register('email', {
required: 'Email обязателен',
pattern: {
value: /^[^\s@]+@[^\s@]+\.[^\s@]+$/,
message: 'Введите корректный email',
},
})}
placeholder="Email"
/>
{errors.email && <p>{errors.email.message}</p>}
<button>Отправить</button>
</form>
);
}
Значения по умолчанию
const { register, handleSubmit } = useForm({
defaultValues: {
name: 'Алиса',
email: 'alice@example.com',
},
});
Когда React Hook Form особенно полезен
- Много полей.
- Нужна валидация.
- Есть повторяющиеся формы в проекте.
- Нужно меньше перерендеров при вводе.
- Форма работает с UI-библиотекой через Controller.
Controller для UI-компонентов
import { Controller, useForm } from 'react-hook-form';
function FormWithSelect() {
const { control, handleSubmit } = useForm();
return (
<form onSubmit={handleSubmit(console.log)}>
<Controller
name="city"
control={control}
defaultValue=""
render={({ field }) => (
<select {...field}>
<option value="">Выберите город</option>
<option value="moscow">Москва</option>
</select>
)}
/>
<button>Сохранить</button>
</form>
);
}
Практический пример: регистрация
В форме регистрации обычно нужны обязательные поля, проверка длины пароля и повтор пароля. Даже без внешних схем валидации React Hook Form закрывает базовую задачу.
function RegisterForm() {
const {
register,
handleSubmit,
watch,
formState: { errors, isSubmitting },
} = useForm();
const password = watch('password');
return (
<form onSubmit={handleSubmit(console.log)}>
<input {...register('email', { required: 'Email обязателен' })} />
{errors.email && <p>{errors.email.message}</p>}
<input
type="password"
{...register('password', {
required: 'Пароль обязателен',
minLength: { value: 6, message: 'Минимум 6 символов' },
})}
/>
<input
type="password"
{...register('repeatPassword', {
validate: value => value === password || 'Пароли не совпадают',
})}
/>
<button disabled={isSubmitting}>Создать аккаунт</button>
</form>
);
}
Что не стоит делать
- Не смешивайте ручной useState для каждого поля и register без необходимости.
- Не прячьте ошибки: пользователь должен понять, что исправить.
- Не отправляйте форму, если handleSubmit уже даёт валидные данные.
- Не забывайте defaultValues при редактировании существующей записи.
Следующий уровень
Когда базовая валидация станет тесной, подключите Zod или Yup через resolvers. Тогда правила формы будут жить в отдельной схеме и их проще переиспользовать на frontend и backend.
Как понять, что форма написана нормально
Форма считается хорошей не тогда, когда она просто отправляет данные, а когда пользователь понимает, что заполнить, где ошибка и что происходит после отправки.
Проверьте форму глазами пользователя: ошибка появляется рядом с полем, кнопка не отправляет пустые данные, после успешной отправки понятно, что произошло. Если эти базовые вещи работают, форма уже лучше большинства учебных примеров.
Проверочный список
- у обязательных полей есть понятные сообщения об ошибке;
- кнопка отправки блокируется во время запроса;
- ошибки показываются рядом с полями, а не где-то внизу страницы;
- значения по умолчанию работают при редактировании записи;
- после успешной отправки понятно, что произошло.
Когда подключать схемы валидации
Если правил мало, хватит встроенной валидации register. Если форма растёт, появляются вложенные объекты, повторяющиеся правила и backend с похожими проверками, лучше подключить Zod или Yup через resolver.
Что улучшить после первого варианта
Добавьте состояние загрузки, обработку ошибки API и reset формы после успешной отправки. Эти три вещи сильнее влияют на качество формы, чем ещё один красивый input.



