Kodokon kodokon.com

Контролируемые формы

Научись управлять каждым полем формы через состояние React, чтобы проверять и отправлять надёжные данные.

8 мин · 3 вопросов

Открыть этот урок в Kodokon

В React форма становится предсказуемой, когда каждое поле контролируемое: отображаемое значение приходит из состояния компонента, и каждое нажатие клавиши проходит через onChange, чтобы обновить это состояние. DOM больше не источник истины - им становится твоё состояние. На практике ты связываешь проп value с переменной состояния и передаёшь обработчик, который вызывает функцию обновления.

JSX
import { useState } from "react";

function EmailField() {
  const [email, setEmail] = useState("");

  return (
    <input
      type="email"
      value={email}
      onChange={(e) => setEmail(e.target.value)}
    />
  );
}
Контролируемое поле: value читает состояние, onChange его записывает.

В настоящей форме редко бывает всего одно поле. Вместо того чтобы нагромождать вызовы useState, собери значения в один объект и напиши универсальный обработчик. Атрибут name каждого поля должен точно совпадать с ключом объекта: именно это подсказывает обработчику, какое свойство обновить.

JSX
const [form, setForm] = useState({
  username: "",
  password: "",
});

function handleChange(e) {
  const { name, value } = e.target;
  setForm((prev) => ({ ...prev, [name]: value }));
}
Один обработчик для всех полей формы.

Остаётся отправка. По умолчанию браузер перезагружает страницу при отправке формы: вызывай e.preventDefault() в начале своего обработчика onSubmit. Это же и самое подходящее место, чтобы проверить данные перед отправкой, ведь всё состояние формы уже под рукой.

JSX
function handleSubmit(e) {
  e.preventDefault();
  if (form.username.trim() === "") {
    alert("Username is required.");
    return;
  }
  console.log("Submitting:", form);
}

return (
  <form onSubmit={handleSubmit}>
    <input
      name="username"
      value={form.username}
      onChange={handleChange}
    />
    <button type="submit">Create account</button>
  </form>
);
Проверяем, затем отправляем, без перезагрузки страницы.

Проверка знаний

Убедись, что запомнил ключевые моменты этого урока.

  1. Что определяет контролируемое поле в React?
    • Его значение хранится в DOM и читается через ref
    • Его значение приходит из состояния, и каждое нажатие клавиши проходит через onChange
    • Оно доступно только для чтения, пока форма не отправлена
    • Оно автоматически проверяет то, что ты набираешь
  2. Ты передаёшь value={email} в <input>, не указав onChange. Что произойдёт?
    • Поле замрёт: набор текста больше ничего не меняет
    • Поле работает нормально, React сам обрабатывает ввод
    • Компонент падает при первом рендере
  3. Зачем нужен e.preventDefault() в обработчике onSubmit?
    • Чтобы предотвратить перезагрузку страницы, вызванную нативной отправкой формы
    • Чтобы автоматически очистить поля формы
    • Чтобы событие не всплывало к родительским компонентам
    • Чтобы отключить HTML-проверку браузера