> Как работает useRef хук в React и для чего он используется (React)
Уровень: senior · Роль: frontend · Категория: Технические вопросы
Компании: ITQ Group МКБ БАНК, Альфа-банк, ДиджиталСектор, VK, Домклик, IT-One, Swetec, Софт Медиа Групп, EPAM, ПСБ, Exness, Сбер
Стек: React
> Пример ответа
Короткий ответ
useRef - это хук React, который создаёт мутабельный объект с свойством .current, сохраняющий своё значение между рендерами. Он используется для доступа к DOM-элементам (например, для фокуса или измерения размеров) и для хранения любых мутабельных данных, изменение которых не должно вызывать ререндер компонента. В отличие от useState, обновление useRef не триггерит повторный рендер.
Подробное объяснение
useRef возвращает объект { current: initialValue }, который живёт всё время жизни компонента. Ключевая особенность - изменение .current не вызывает ререндер, что делает его идеальным для хранения значений, не влияющих на UI.
Основные сценарии использования:
- Доступ к DOM-элементам: передаётся как
refв JSX-элемент, после монтирования.currentуказывает на DOM-узел. Позволяет программно управлять фокусом, анимациями, интеграцией с библиотеками (например, D3). - Хранение мутабельных данных: таймеры, идентификаторы интервалов, предыдущие значения пропсов, флаги для предотвращения повторных вызовов эффектов.
- Сохранение ссылок на функции или объекты без потери при ререндерах - полезно для колбэков в
useEffectилиuseCallback.
Важно: useRef не заменяет useState для данных, от которых зависит отображение. Изменение ref не даёт React знать, что нужно обновить UI.
На практике
В реальных проектах useRef часто применяется для:
- Фокуса на поле ввода при монтировании формы
- Интеграции с анимационными библиотеками (например, GSAP)
- Хранения предыдущего значения пропса для сравнения
- Создания ссылок на элементы в виртуализированных списках
- Отмены запросов через AbortController в эффектах
Типичный паттерн - комбинация с useEffect для работы с DOM после рендера. Также useRef используется в кастомных хуках для создания стабильных ссылок на функции, избегая лишних ререндеров дочерних компонентов.
Пример кода
JSXimport { useRef, useEffect } from 'react';function AutoFocusInput() {const inputRef = useRef(null);useEffect(() => {// Фокус на инпуте после монтированияinputRef.current?.focus();}, []);return <input ref={inputRef} type="text" />;}function Timer() {const intervalRef = useRef(null);const startTimer = () => {intervalRef.current = setInterval(() => {console.log('Tick');}, 1000);};const stopTimer = () => {clearInterval(intervalRef.current);};return (<div><button onClick={startTimer}>Start</button><button onClick={stopTimer}>Stop</button></div>);}function PreviousValue({ value }) {const prevRef = useRef();useEffect(() => {prevRef.current = value;});return (<div><p>Current: {value}</p><p>Previous: {prevRef.current}</p></div>);}
Как отвечать на собеседовании
Начни с краткого определения, затем перечисли основные кейсы использования. Подчеркни разницу с useState - отсутствие ререндера при изменении. Упомяни, что useRef - это способ сохранить мутабельное значение между рендерами, не засоряя замыкания. Приведи пример с DOM-элементом и с хранением таймера. Для уровня senior добавь про использование в кастомных хуках и про то, что ref можно передавать через forwardRef.
Что проверяет интервьюер
- Понимание разницы между
useRefиuseState - Знание, что изменение
.currentне вызывает ререндер - Умение применять
useRefдля работы с DOM и хранения данных - Понимание проблем замыканий и как
useRefпомогает их решать - Знание
forwardRefдля передачи ref через компоненты
Типичные ошибки
- Попытка использовать
useRefдля данных, от которых зависит UI (нуженuseState) - Чтение
.currentв рендере до того, как элемент смонтирован (получишьnull) - Изменение
.currentвнутри рендера напрямую (нарушение принципов React, лучше делать в эффектах или обработчиках) - Забывание, что
useRefне инициализируется заново при ререндерах (это фича, а не баг) - Использование
useRefвместоuseCallbackдля стабилизации ссылок на функции (хотя это работает, но менее читаемо)
> Похожие задачи по frontend
Что такое виртуальный DOM и зачем он нужен
Что такое React.memo и как он помогает оптимизировать рендеринг
Как работает жизненный цикл React-компонентов
В чем отличие useEffect от useLayoutEffect в React
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью