Как использовать с UseRef?
Хуки
useRef используется двумя способами: как ссылка на DOM-узел и как хранилище мутируемого значения без ререндеров.
Способ 1: доступ к DOM
const inputRef = useRef(null);
useEffect(() => {
inputRef.current.focus(); // узел доступен после коммита
}, []);
<input ref={inputRef} />Применение: фокус, scrollIntoView(), измерения (getBoundingClientRect()), медиа (play/pause), передача контейнера сторонней библиотеке (карта, чарт). До монтирования current === null, после размонтирования — снова null.
Способ 2: значение между рендерами
const timerRef = useRef(null);
const start = () => { timerRef.current = setInterval(tick, 1000); };
const stop = () => clearInterval(timerRef.current);Применение: id таймеров, инстансы (WebSocket, AbortController, observers), предыдущие значения props, флаги (isMounted, «первый рендер»), «свежие» колбэки для стабильных подписок.
Правила
- Запись в
ref.currentне вызывает ререндер — отображаемые данные держите в state. - Не читать/писать ref во время рендера (кроме ленивой инициализации) — только в эффектах и обработчиках; рендер обязан быть чистым.
- Не менять через ref то, чем управляет React (value управляемого инпута, классы из JSX) — перезапишется.
- Ref на кастомный компонент — через forwardRef (React 19: обычный проп); наружу отдавать узкий API через useImperativeHandle.
- Нужна реакция на появление узла — callback ref (
ref={(node) => ...}).
Коротко для собеседования
Два применения: ссылка на DOM (фокус, измерения, скролл, интеграции — доступна после коммита) и мутируемое хранилище между рендерами (таймеры, инстансы, флаги, предыдущие значения). Запись в current не рендерит; работать с ref — в эффектах и обработчиках, не в теле рендера.