Controlled vs Uncontrolled Components в React: в чём разница и что спрашивают на интервью
Подробно разбираем controlled и uncontrolled компоненты в React: источник истины, производительность, ошибки, предупреждения и аргументацию выбора на собеседованиях junior/middle.
- Что такое Controlled Component
- Определение простыми словами
- Пример
- Что происходит при вводе
- Что такое Uncontrolled Component
- Определение
- Пример
- Главное отличие: источник истины
- Почему controlled-компоненты чаще используются
- Производительность и controlled-компоненты
- Когда Uncontrolled — лучшее решение
- Смешанный подход (Hybrid)
- Частые вопросы на интервью
- В чём разница controlled и uncontrolled?
- Какой подход лучше?
- Почему input может стать read-only?
- Что будет, если убрать onChange?
- Можно ли переключить uncontrolled в controlled?
- Почему React ругается на смену controlled/uncontrolled?
- Ошибка: “A component is changing an uncontrolled input to be controlled”
- Controlled формы и библиотеки
- Formik
- react-hook-form
- Частые ошибки кандидатов
- Как правильно отвечать на интервью
- FAQ
- Controlled медленнее?
- Можно ли смешивать подходы?
- Что лучше для больших форм?
- Нужно ли всегда хранить всё в state?
- Итоги
Тема форм почти всегда всплывает на собеседованиях, потому что она быстро показывает уровень кандидата. На простом UI оба подхода работают, но в реальном проекте выбор между controlled и uncontrolled влияет на архитектуру формы, валидацию, производительность и поддержку кода.
Фраза «controlled — это когда есть value» слишком поверхностная. Интервьюеру важно, понимаете ли вы источник истины, жизненный цикл обновлений, причины предупреждений React и практические компромиссы в больших формах.
Большинство ошибок возникает не из-за синтаксиса, а из-за неверной модели: например, смешали defaultValue и value, случайно перевели поле из uncontrolled в controlled, не объяснили поведение file input или начали контролировать все подряд без оценки стоимости.
В этой статье разберем обе модели на инженерном уровне: как они работают, где лучше применять каждую, какие вопросы задают на junior/middle и как отвечать так, чтобы было видно зрелое понимание.
Если хотите связать эту тему с ререндерами и мемоизацией, смотрите React.memo, useMemo и useCallback: оптимизация без магии и Оптимизация React: что спрашивают на middle-собеседованиях.
Больше вопросов в Telegram
Ежедневные разборы и реальные кейсы с интервью.
Что такое Controlled Component
Определение простыми словами
Controlled-компонент — это поле формы, значение которого хранится в state React.
Ключевые признаки:
- текущее значение живет в state;
- React полностью контролирует отображаемое значение поля;
- UI является функцией от state.
Именно поэтому controlled-подход дает высокую предсказуемость: состояние формы централизовано и прозрачно.
Пример
const [value, setValue] = useState("");
<input
value={value}
onChange={(e) => setValue(e.target.value)}
/>
Что происходит при вводе
Пошагово:
- Пользователь вводит символ.
- Срабатывает
onChange. - Обновляется state через
setValue. - Компонент ререндерится.
- Новое значение из state снова попадает в
input.
Эта петля и есть controlled-модель: значение поля не «живет само по себе» в DOM, оно всегда приходит из React-состояния.
Что такое Uncontrolled Component
Определение
Uncontrolled-компонент — это поле, где источником истины остается DOM.
Это означает:
- React не хранит текущее значение поля в state;
- значение читается напрямую из DOM, обычно через
ref; - реактивный контроль минимален.
Пример
const inputRef = useRef<HTMLInputElement | null>(null);
<input ref={inputRef} />
Чтение значения:
const currentValue = inputRef.current?.value;
Подход удобен, когда не нужна реактивная логика на каждый символ и значение достаточно получить в момент submit.
Главное отличие: источник истины
| Controlled | Uncontrolled |
|---|---|
| State в React | DOM |
| Полный контроль | Минимальный контроль |
| Частые ререндеры | Меньше ререндеров |
| Удобно валидировать и управлять UI в реальном времени | Проще для простых форм и нативных сценариев |
Если запомнить только одну идею, запоминайте эту: выбор между подходами — это выбор места, где хранится «правда» о значении поля.
Почему controlled-компоненты чаще используются
В production-проектах controlled-подход часто выигрывает, когда нужна сложная интерактивная логика:
- валидация в реальном времени;
- условное отображение блоков формы;
- блокировка кнопки submit по правилам;
- единая схема состояния для бизнес-логики;
- интеграция с form-слоем и UI-правилами.
Типичный вопрос:
Почему в реальных проектах чаще используют controlled?
Сильный ответ: потому что controlled-форма предсказуема, удобна для динамических правил и проще в сопровождении там, где поведение формы зависит от состояния в нескольких местах интерфейса.
Производительность и controlled-компоненты
У controlled-полей каждый ввод действительно вызывает setState, а значит и ререндеры.
Проблемы начинаются, когда:
- state формы слишком глобальный;
- при каждом вводе ререндерится большое дерево;
- тяжелые вычисления привязаны к каждому символу.
Как оптимизировать большие формы:
- разделять state по секциям/полям, а не хранить «всё в одном объекте» без необходимости;
- изолировать тяжелые поддеревья;
- использовать
React.memoтам, где это подтверждено профилированием; - выносить дорогую валидацию из hot-path ввода (debounce, onBlur, server-side).
То есть не «избегать controlled», а строить его осознанно.
Когда Uncontrolled — лучшее решение
Uncontrolled-подход часто рационален в следующих случаях:
- простые формы без сложной динамики;
- нативная HTML-механика (
FormData, submit без реактивного UI); - интеграция со сторонними библиотеками, которые работают через ref/DOM;
- большие формы, где критичен минимум ререндеров;
file input(его нельзя полноценно контролировать как обычный текстовыйvalue).
На практике это не «устаревший подход», а нормальный инструмент, если он соответствует задаче.
Смешанный подход (Hybrid)
В реальных приложениях часто используют гибрид:
- часть полей controlled (где нужна реактивность);
- часть полей uncontrolled (где достаточно чтения на submit);
defaultValueдля начального значения без постоянного контроля;- управление отдельными полями только в ключевых шагах.
Этот подход регулярно обсуждают на middle-собеседованиях, потому что он требует зрелой аргументации, а не бинарного выбора «только controlled» или «только uncontrolled».
Частые вопросы на интервью
В чём разница controlled и uncontrolled?
В источнике истины: в controlled значение хранится в state React, в uncontrolled — в DOM.
Какой подход лучше?
Нет универсально лучшего. Controlled удобнее для сложной логики, uncontrolled проще и может быть эффективнее в простых сценариях.
Почему input может стать read-only?
Если вы задали value, но не обновляете его через onChange, поле остается привязанным к неизменяемому state и визуально «не печатается».
Что будет, если убрать onChange?
Для controlled-поля это обычно приведет к предупреждению и некорректному поведению ввода, потому что value фиксирован, а путь обновления отсутствует.
Можно ли переключить uncontrolled в controlled?
Технически можно, но это плохая практика внутри жизненного цикла одного поля. React предупреждает, потому что модель управления полем меняется на лету и это часто сигнал бага.
Почему React ругается на смену controlled/uncontrolled?
Потому что поле должно иметь стабильную модель управления от первого рендера. Переход между режимами создает неочевидное поведение и ломает предсказуемость формы.
Ошибка: “A component is changing an uncontrolled input to be controlled”
Разбор типового кейса:
- на первом рендере
valueравенundefined(поле фактически uncontrolled); - позже
valueстановится строкой (поле становится controlled); - React показывает предупреждение о смене режима.
Почему это важно:
- предупреждение почти всегда указывает на дырку в инициализации данных;
- поведение формы может стать нестабильным;
- такие баги сложно воспроизводить в edge-кейсах.
Как исправляют:
- задают стабильное начальное значение (
""для строкового поля); - не смешивают
valueиdefaultValueв одном контроле; - держат выбранную модель постоянной на протяжении жизни поля.
Controlled формы и библиотеки
Formik
Formik исторически строится вокруг controlled-логики: значения полей, touched/errors и обработчики привязаны к состоянию формы.
Плюсы:
- предсказуемая модель;
- удобный контроль сложных валидаторов;
- прозрачная сериализация формы.
Минус:
- на очень больших формах без оптимизаций можно получить заметные ререндеры.
react-hook-form
react-hook-form часто выбирает uncontrolled-подход как базу:
- опирается на refs;
- минимизирует количество ререндеров;
- использует подписки на конкретные поля.
Именно поэтому библиотека хорошо масштабируется на длинных формах и остается отзывчивой при большом количестве инпутов.
Сильный ответ на интервью: react-hook-form не «лучше всегда», а лучше в сценариях, где нужна производительность и локальность обновлений без полного controlled-цикла на каждый символ.
Частые ошибки кандидатов
- Путают
defaultValueиvalue. - Не понимают источник истины для поля.
- Говорят «controlled всегда лучше» без контекста.
- Не знают особенности
file input. - Не могут объяснить предупреждение про смену controlled/uncontrolled.
Именно эти ошибки чаще всего показывают, что человек запомнил термин, но не понял модель.
Как правильно отвечать на интервью
Рабочая формула:
- Controlled — React хранит значение в state.
- Uncontrolled — значение хранит DOM, React читает его при необходимости.
- Controlled удобнее для сложной и реактивной логики.
- Uncontrolled проще и иногда быстрее в простых или больших формах.
- Выбор зависит от задачи, UX и требований к производительности.
Если вы можете дополнить ответ кейсом из практики (например, почему в одном проекте выбрали react-hook-form), это сразу поднимает уровень ответа до middle.
Разбери формы и валидацию до уровня собеседования
Тренируем аргументацию выбора: controlled vs uncontrolled, производительность больших форм и типичные баги.
FAQ
Controlled медленнее?
Не обязательно. Он может давать больше ререндеров, но при нормальной декомпозиции формы и локализации state работает быстро и предсказуемо.
Можно ли смешивать подходы?
Да. Гибридный подход очень распространен и часто оптимален для реальных задач.
Что лучше для больших форм?
Обычно выбирают не «один режим на всё», а комбинацию: локальный controlled там, где нужна логика, и оптимизированные uncontrolled-паттерны там, где важна производительность.
Нужно ли всегда хранить всё в state?
Нет. В state стоит хранить только то, что действительно нужно для реактивного UI и бизнес-правил.
Итоги
Controlled дает предсказуемость, uncontrolled — простоту.
Ключевое различие между ними — источник истины, и именно его обычно проверяют на собеседованиях.
На middle уровне важна не догма «что лучше», а аргументация выбора под конкретные требования формы, UX и производительности.
Автор
Lexicon Team
Читайте также
frontend
React формы: сложные вопросы, которые задают на собеседовании и в production
Разбираем сложные вопросы по React-формам: controlled и uncontrolled поля, асинхронную валидацию, SSR, производительность, race conditions и типичные ошибки.
frontend
System design для frontend разработчика: как мыслить системно, а не только компонентами
Практический разбор system design для frontend разработчика: границы ответственности, данные, производительность, ошибки и сильный ответ на интервью.
frontend
React patterns, которые спрашивают на senior интервью: не определения, а архитектурные компромиссы
Разбираем React patterns для senior интервью: HOC, Render Props, Compound Components, controlled/uncontrolled, headless API и критерии выбора.