Управляемый input в React: текст, checkbox и сброс формы

Управляемый input в React: текст, checkbox и сброс формы
Содержание статьи

У управляемого поля React текущее значение задаётся состоянием компонента. Для текста используют value, для checkbox используют checked. При вводе onChange сразу обновляет это состояние. Если передать значение без обработчика, редактирование не будет работать как ожидается.

В примере Mentoring.digital создадим учебную форму заявки. Она показывает введённые данные на странице и ничего не отправляет.

Один источник значений для полей

Поместите компонент в App.jsx существующего React-проекта. Название храним строкой, согласие булевым значением. Текст результата живёт отдельно, чтобы после нажатия кнопки видеть снимок отправленных данных.

import { useState } from "react";

export default function App() {
  const [topic, setTopic] = useState("");
  const [accepted, setAccepted] = useState(false);
  const [result, setResult] = useState("");

  function submit(event) {
    event.preventDefault();
    const cleanTopic = topic.trim();
    if (!cleanTopic || !accepted) {
      setResult("Введите тему и отметьте согласие");
      return;
    }
    setResult(`Тема: ${cleanTopic}`);
  }

  function resetForm() {
    setTopic("");
    setAccepted(false);
    setResult("");
  }

  return (
    <form onSubmit={submit}>
      <label>
        Тема разбора
        <input
          name="topic"
          value={topic}
          onChange={event => setTopic(event.target.value)}
        />
      </label>
      <label>
        <input
          type="checkbox"
          name="accepted"
          checked={accepted}
          onChange={event => setAccepted(event.target.checked)}
        />
        Согласен с условиями учебного примера
      </label>
      <button type="submit">Проверить</button>
      <button type="button" onClick={resetForm}>Сбросить</button>
      <p role="status">{result}</p>
    </form>
  );
}

Почему сброс тоже меняет состояние

В нашем примере кнопка вызывает три setter-функции. Поля и сообщение возвращаются к выбранным начальным значениям. Кнопка имеет type="button", чтобы не отправлять форму. Сброс DOM-поля без обновления состояния не решает задачу управляемого компонента.

Проверка cleanTopic выполняется при отправке. Во время набора setTopic сохраняет введённую строку без преобразований. Поэтому пользователь может спокойно поставить пробел между словами и отредактировать середину текста. Правило очистки применяется к результату, а не вмешивается в каждый ввод.

Частые причины неправильного поведения

defaultValue задаёт начальное значение неуправляемого поля, а не его текущее состояние. Не смешивайте его с value. Не начинайте value с undefined или null, чтобы позже заменить строкой. Если данные пришли из API, подготовьте строковое значение до передачи в поле. Для checkbox читайте target.checked, а не target.value.

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

Сценарии проверки формы

  • Введите тему, поставьте отметку и нажмите «Проверить». В результате должна появиться очищенная тема.
  • Введите только пробелы. Должно появиться сообщение о необходимости темы.
  • Снимите отметку и повторите проверку.
  • Нажмите «Сбросить». Текст, отметка и результат должны очиститься вместе.
  • Переместите курсор в середину текста и допишите слово. Проверьте сохранение позиции ввода.

Для следующего упражнения добавьте второе поле и заранее определите, должен ли общий сброс очищать оба. Такие компоненты удобно разбирать на курсе React с практикой. Если форма уже связана с запросами, обсудите состояния ожидания и ошибки с наставником по React.

Похожие статьи по данной теме