← Назад к вопросам
Если сохранить inpput в useRef, будет ли он считаться контроллируемым
2.2 Middle🔥 281 комментариев
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
useRef для Input: Контролируемый или нет?
Короткий ответ
Нет, не будет контролируемым. Если вы сохраняете input в useRef, это остаётся неконтролируемым компонентом. Контролируемость зависит от того, кто управляет значением value — React состояние или DOM.
Контролируемый vs Неконтролируемый
Контролируемый (Controlled)
React управляет значением через state:
function ControlledInput() {
const [value, setValue] = useState('');
return (
<input
value={value}
onChange={(e) => setValue(e.target.value)}
/>
);
}
Характеристики:
- Значение хранится в React состоянии
- React отрисовывает компонент заново при изменении
- Можно легко валидировать, трансформировать
- Синхронизация между состоянием и DOM гарантирована
Неконтролируемый (Uncontrolled)
DOM управляет своим значением, React только читает:
function UncontrolledInput() {
const inputRef = useRef(null);
const handleSubmit = () => {
console.log(inputRef.current.value); // Читаем из DOM
};
return (
<>
<input ref={inputRef} />
<button onClick={handleSubmit}>Submit</button>
</>
);
}
Характеристики:
- Значение хранится в DOM, не в React
- useRef просто создаёт ссылку на DOM элемент
- React НЕ перерисовывает при изменении
- Нет синхронизации React state и DOM
Примеры: useRef вариант
function RefExample() {
const inputRef = useRef(null);
// Это НЕКОНТРОЛИРУЕМЫЙ input
return (
<>
<input ref={inputRef} defaultValue="Initial" />
<button onClick={() => alert(inputRef.current.value)}>
Read Value
</button>
</>
);
}
// Даже если вы сохраняете значение в useRef
const inputValue = useRef('');
inputValue.current = 'something'; // Это не подвязано к input!
<input ref={inputRef} /> // Это всё равно неконтролируемый
Почему это важно
Проблема: попытка контролировать через useRef
// ПЛОХО: смешивание подходов
function BadExample() {
const valueRef = useRef('');
const inputRef = useRef(null);
const handleChange = () => {
valueRef.current = inputRef.current.value; // Только читаем
};
// Нельзя перерисовать input снаружи
const setInputValue = (newValue) => {
valueRef.current = newValue;
// inputRef.current.value = newValue; // Приходится манипулировать DOM!
};
return <input ref={inputRef} onChange={handleChange} />;
}
Правильно: контролируемый компонент
function GoodExample() {
const [value, setValue] = useState('');
return (
<>
<input
value={value}
onChange={(e) => setValue(e.target.value)}
/>
<button onClick={() => setValue('')}>Clear</button>
</>
);
}
Когда использовать что
Используйте контролируемый (useState)
- Нужна валидация в реальном времени
- Нужно изменить значение программно
- Зависимости от других полей (например, если поле A заполнено, очистить B)
- Нужно вычислять производные данные
function Form() {
const [email, setEmail] = useState('');
const [errors, setErrors] = useState('');
const handleChange = (e) => {
const value = e.target.value;
setEmail(value);
// Валидация в реальном времени
if (!value.includes('@')) {
setErrors('Invalid email');
} else {
setErrors('');
}
};
return (
<>
<input value={email} onChange={handleChange} />
{errors && <span>{errors}</span>}
</>
);
}
Используйте неконтролируемый (useRef)
- Нужно просто прочитать значение при сабмите
- Интеграция с не-React кодом
- Фокус/блюр события
- Файловые input
function FileInput() {
const fileRef = useRef(null);
const handleUpload = () => {
const file = fileRef.current.files[0];
console.log(file);
};
return (
<>
<input ref={fileRef} type="file" />
<button onClick={handleUpload}>Upload</button>
</>
);
}
function FocusInput() {
const inputRef = useRef(null);
return (
<>
<input ref={inputRef} />
<button onClick={() => inputRef.current.focus()}>
Focus
</button>
</>
);
}
Рекомендация
По умолчанию используйте контролируемые компоненты (useState). Переходите на useRef только если есть конкретная причина:
// 1. Контролируемый (по умолчанию)
const [value, setValue] = useState('');
<input value={value} onChange={(e) => setValue(e.target.value)} />
// 2. Если нужно только читать — неконтролируемый
const ref = useRef(null);
<input ref={ref} defaultValue="" />
const value = ref.current.value; // При необходимости
Заключение
useRef не делает input контролируемым. Контролируемость определяется тем, управляет ли React значением через state. useRef просто создаёт ссылку на DOM элемент, не влияя на тип управления.
Похожие вопросы
- В чем разница между методами Promise.race и Promise.any?
- Когда могут обновится props?
- Можно ли поделить на группы типы данных в JavaScript?
- Почему библиотека React Query не является state manager?
- Какие плюсы и минусы семантической верстки для людей?
- Пишется ли проект полностью на Context в React
- Что нужно добавить в useEffect в React чтобы снять обработчик после закрытия модального окна?
- Какая конструкция в JavaScript может сделать новый scope для this?
- Какие есть очереди в Event Loop кроме micro и macro tasks?
- Как устроен рендеринг в React.js?
- Какое свойство дожидается выполнения всех Promise?
- Можно ли вызвать стрелочную функцию до объявления?
- Какие знаешь состояния useEffect?
- Какие знаешь способы манипулирования контекстом функции в JavaScript?
- В каких случаях нельзя в key в React ставить индекс элемента массива
- Какая область видимости у переменной в блоке цикла?
- Можно ли оиспользовать Bind или Apply на стрелочной функции?
- Выполнится первее Promise.resolve() или setTimeout с нулевой задержкой
- Почему Promise выполняется раньше setTimeout?
- Может ли быть замыкание у одной функции?