Зачем нужен хук useRef?
Хуки
useRef — хук, создающий мутируемый контейнер { current: value }, который живёт всё время жизни компонента и не вызывает перерендер при изменении.
Сигнатура
const inputRef = useRef(null); // для DOM-элемента
const timerRef = useRef(undefined); // для любого значенияДва основных сценария
Доступ к DOM-элементу:
const SearchField = () => {
const inputRef = useRef(null);
useEffect(() => {
inputRef.current.focus(); // императивный доступ к DOM
}, []);
return <input ref={inputRef} />;
};Хранение значения между рендерами без перерендера:
const Stopwatch = () => {
const timerRef = useRef(null);
const start = () => {
timerRef.current = setInterval(tick, 1000);
};
const stop = () => clearInterval(timerRef.current);
// ...
};Так хранят id таймеров, WebSocket-соединения, предыдущие значения props, флаги «компонент смонтирован».
Отличие от useState
- Изменение
ref.current— синхронное и не вызывает перерендер. - Изменение state — асинхронное (батчится) и вызывает перерендер.
- Данные, влияющие на то, что видит пользователь, — в state; служебные данные — в ref.
Нюансы
- Не читайте и не пишите
ref.currentво время рендера — только в эффектах и обработчиках. ref.currentдля DOM заполняется после коммита, поэтому в первом рендере он ещёnull.
Коротко для собеседования
useRef создаёт стабильный контейнер { current }, переживающий рендеры. Два применения: ссылка на DOM-элемент (фокус, измерения) и хранение мутируемых данных, изменение которых не должно вызывать перерендер (таймеры, подписки, предыдущие значения).