← Назад к вопросам
Если сохранить inpput в useRef, будет ли он считаться контроллируемым
2.2 Middle🔥 281 комментариев
#React
Комментарии (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 элемент, не влияя на тип управления.