Работа с формами

В React формы могут быть реализованы двумя основными способами: через контролируемые и неконтролируемые компоненты. Выбор между ними зависит от того, как вы управляете данными ввода — через состояние React или напрямую через DOM.

В контролируемых компонентах значение поля ввода управляется состоянием React. Это означает, что:

  • Значение элемента задаётся через пропс value (или checked для чекбоксов)
  • Любое изменение обрабатывается через onChange, который обновляет состояние
  • React всегда «владеет» текущим значением

Пример:

function ControlledForm() {
  const [name, setName] = useState('');

  return (
    <form>
      <input
        value={name}
        onChange={(e) => setName(e.target.value)}
        placeholder="Введите имя"
      />
      <p>Вы ввели: {name}</p>
    </form>
  );
}

Контролируемые компоненты — рекомендуемый подход в большинстве случаев, так как они:

  • Предсказуемы
  • Позволяют легко валидировать и преобразовывать ввод
  • Интегрируются с состоянием приложения

В неконтролируемых компонентах данные хранятся в самом DOM-элементе. React не управляет значением — вместо этого вы используете ref, чтобы прочитать его при необходимости.

Пример:

function UncontrolledForm() {
  const inputRef = useRef(null);

  function handleSubmit(e) {
    e.preventDefault();
    console.log('Значение:', inputRef.current.value);
  }

  return (
    <form onSubmit={handleSubmit}>
      <input ref={inputRef} defaultValue="" />
      <button type="submit">Отправить</button>
    </form>
  );
}
  • Форма очень большая, и управление каждым полем через состояние избыточно
  • Интеграция с библиотеками, которые работают напрямую с DOM
  • Временные или одноразовые формы, где валидация не требуется

Выбор между ref и useState для форм зависит от цели:

  • Используйте состояние (useState), если:

    • Значение влияет на отображение (например, предварительный просмотр, кнопка активна/неактивна)
    • Требуется валидация в реальном времени
    • Данные нужны в других частях приложения
  • Используйте ref, если:

    • Значение нужно только в момент отправки
    • Вы работаете с большим количеством полей, и синхронизация состояния слишком затратна
    • Элемент используется для технических целей (например, фокусировка)

Важно: даже в неконтролируемых формах можно комбинировать подходы — например, использовать ref для большинства полей, но state для кнопки «Отправить», которая должна быть недоступна, пока не заполнено обязательное поле.