← Назад к вопросам

В чем разница между контролируемыми и неконтролируемыми компонентами?

2.0 Middle🔥 202 комментариев
#JavaScript Core

Комментарии (2)

🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Контролируемые и неконтролируемые компоненты в React

Контролируемые и неконтролируемые компоненты — это два разных подхода к управлению состоянием формовых элементов в React. Различие заключается в том, где хранится и управляется значение элемента: в React-состоянии или в DOM.

Контролируемые компоненты (Controlled Components)

В контролируемом компоненте значение элемента полностью управляется React через состояние. Браузер не хранит значение — это делает React.

Характеристики:

  • Значение элемента привязано к состоянию React
  • Каждое изменение пользователем вызывает обновление состояния
  • React является единственным источником истины (single source of truth)
  • Позволяет легко валидировать, фильтровать и преобразовывать входные данные в реальном времени
import { useState } from 'react';

function ControlledInput() {
  const [value, setValue] = useState('');

  const handleChange = (e) => {
    setValue(e.target.value);
  };

  return (
    <div>
      <input 
        type="text" 
        value={value} 
        onChange={handleChange}
        placeholder="Введите текст"
      />
      <p>Вы ввели: {value}</p>
    </div>
  );
}

Преимущества:

  • Полный контроль над поведением элемента
  • Легко реализовать валидацию в реальном времени
  • Можно программно устанавливать значение
  • Проще отследить изменения и синхронизировать с другими данными
  • Удобно реализовать условное отключение кнопки отправки при неполных данных

Недостатки:

  • Больше кода и логики
  • Может быть медленнее при частых обновлениях на больших формах
  • Требует постоянной синхронизации состояния
// Пример с валидацией
function ControlledInputWithValidation() {
  const [email, setEmail] = useState('');
  const [error, setError] = useState('');

  const handleChange = (e) => {
    const value = e.target.value;
    setEmail(value);
    
    if (!value.includes('@')) {
      setError('Email должен содержать @');
    } else {
      setError('');
    }
  };

  return (
    <div>
      <input 
        type="email" 
        value={email} 
        onChange={handleChange}
      />
      {error && <p style={{ color: 'red' }}>{error}</p>}
    </div>
  );
}

Неконтролируемые компоненты (Uncontrolled Components)

В неконтролируемом компоненте значение хранится в самом DOM-элементе. React не отслеживает и не управляет этим значением. Доступ к значению осуществляется через refs (ссылки на DOM-элементы).

Характеристики:

  • Значение хранится в DOM (браузер управляет состоянием)
  • React не контролирует значение элемента
  • Для получения значения используются refs (useRef)
  • Похожи на обычные HTML-элементы
import { useRef } from 'react';

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

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

  return (
    <form onSubmit={handleSubmit}>
      <input 
        type="text" 
        ref={inputRef}
        placeholder="Введите текст"
      />
      <button type="submit">Отправить</button>
    </form>
  );
}

Преимущества:

  • Меньше кода и проще реализация
  • Хороший выбор для простых форм
  • Может быть быстрее при большом количестве полей
  • Естественнее интегрируется с DOM

Недостатки:

  • Сложнее валидировать в реальном времени
  • Нельзя программно отключить кнопку до заполнения
  • React не имеет полного контроля над состоянием формы
  • Сложнее синхронизировать с другими данными
  • Требует доступа к DOM напрямую (через refs)
// Пример с несколькими полями
function UncontrolledForm() {
  const nameRef = useRef(null);
  const emailRef = useRef(null);

  const handleSubmit = (e) => {
    e.preventDefault();
    const formData = {
      name: nameRef.current.value,
      email: emailRef.current.value
    };
    console.log(formData);
  };

  return (
    <form onSubmit={handleSubmit}>
      <input ref={nameRef} type="text" placeholder="Имя" />
      <input ref={emailRef} type="email" placeholder="Email" />
      <button type="submit">Отправить</button>
    </form>
  );
}

Практические рекомендации

  1. Используй контролируемые компоненты для:

    • Форм с валидацией
    • Когда нужна валидация в реальном времени
    • Условного отключения кнопок отправки
    • Синхронизации данных между несколькими полями
    • Большинства случаев в React
  2. Используй неконтролируемые компоненты для:

    • Простых одноразовых форм
    • Интеграции с не-React кодом
    • File input (загрузка файлов)
    • Когда нужна максимальная производительность с большим количеством полей

Выбор между контролируемыми и неконтролируемыми компонентами зависит от требований проекта, сложности формы и производительности.

В чем разница между контролируемыми и неконтролируемыми компонентами? | PrepBro