Формы и controlled inputs
Связываем поля ввода с состоянием так, что React становится единственным источником правды о форме.
Управляемый компонент (controlled input) — поле, значение которого хранится в состоянии React и задаётся через
value, а меняется черезonChange.
Идея: состояние — источник правды
Обычное HTML-поле само хранит свой текст. В React предпочитают, чтобы значение жило в состоянии: так его легко прочитать, проверить, очистить. Связка из двух частей:
value={text}— поле всегда показывает значение из состояния;onChange— при вводе записывает новое значение в состояние.
function NameInput() {
const [name, setName] = useState("");
return (
<div>
<input
value={name}
onChange={(e) => setName(e.target.value)}
/>
<p>Привет, {name || "незнакомец"}!</p>
</div>
);
}
Получается цикл: пользователь печатает → onChange обновляет состояние → React перерисовывает → поле показывает новое value. Состояние и поле всегда синхронны.
Почему именно так
Раз значение в состоянии, вы в любой момент можете им управлять: подставить значение по умолчанию, очистить поле (setName("")), запретить определённые символы, показать ошибку. С неуправляемым полем это сделать гораздо сложнее.
Несколько полей — один объект
Для формы с многими полями держат состояние объектом и обновляют его иммутабельно по имени поля:
function SignupForm() {
const [form, setForm] = useState({ email: "", password: "" });
function handleChange(e) {
const { name, value } = e.target;
setForm((prev) => ({ ...prev, [name]: value }));
}
return (
<form>
<input name="email" value={form.email} onChange={handleChange} />
<input name="password" value={form.password} onChange={handleChange} />
</form>
);
}
Один обработчик обслуживает все поля: по e.target.name он понимает, какое поле менять, а [name]: value (вычисляемое имя свойства) обновляет нужный ключ.
Чекбоксы: checked вместо value
У чекбокса состояние булево, и связывают его через checked и e.target.checked:
function Agree() {
const [agree, setAgree] = useState(false);
return (
<label>
<input
type="checkbox"
checked={agree}
onChange={(e) => setAgree(e.target.checked)}
/>
Согласен с условиями
</label>
);
}
Памятка по полям
| Поле | Что связывать | Что читать |
| text / textarea | value | e.target.value |
| checkbox | checked | e.target.checked |
| select | value | e.target.value |
Итог
- Управляемое поле:
valueиз состояния +onChange, записывающийe.target.valueобратно. - Для многих полей держат объект и обновляют ключ через
[name]: value. - У чекбокса используют
checkedиe.target.checkedвместоvalue.