Контролируемое поле: значение в state, каждое нажатие проходит через React. Неконтролируемое: значение хранит DOM, читаем по ref или из FormData при отправке.
const [email, setEmail] = useState("");
<input value={email} onChange={(e) => setEmail(e.target.value)} />
Что важно знать
- Контролируемые удобны для мгновенной валидации и зависимых полей, но большая форма перерисовывается на каждый символ.
- React Hook Form использует неконтролируемые поля и подписки — быстро и мало кода; со схемой Zod валидация описывается один раз и даёт типы.
- Действия форм React 19 (
action,useActionState) — отправка без ручного управления состоянием загрузки. - Доступность: подписи, сообщения об ошибках, связанные через
aria-describedby, фокус на первом ошибочном поле.