> Как работает 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.

Основные сценарии использования:

  1. Доступ к DOM-элементам: передаётся как ref в JSX-элемент, после монтирования .current указывает на DOM-узел. Позволяет программно управлять фокусом, анимациями, интеграцией с библиотеками (например, D3).
  2. Хранение мутабельных данных: таймеры, идентификаторы интервалов, предыдущие значения пропсов, флаги для предотвращения повторных вызовов эффектов.
  3. Сохранение ссылок на функции или объекты без потери при ререндерах - полезно для колбэков в useEffect или useCallback.

Важно: useRef не заменяет useState для данных, от которых зависит отображение. Изменение ref не даёт React знать, что нужно обновить UI.

На практике

В реальных проектах useRef часто применяется для:

  • Фокуса на поле ввода при монтировании формы
  • Интеграции с анимационными библиотеками (например, GSAP)
  • Хранения предыдущего значения пропса для сравнения
  • Создания ссылок на элементы в виртуализированных списках
  • Отмены запросов через AbortController в эффектах

Типичный паттерн - комбинация с useEffect для работы с DOM после рендера. Также useRef используется в кастомных хуках для создания стабильных ссылок на функции, избегая лишних ререндеров дочерних компонентов.

Пример кода

JSX
import { 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 для стабилизации ссылок на функции (хотя это работает, но менее читаемо)

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью