Логотип YeaHub

База вопросов

Собеседования

Тренажёр

База ресурсов

Обучение

Навыки

Войти

Выбери, каким будет IT завтра — вместе c нами!

YeaHub — это полностью открытый проект, призванный объединить и улучшить IT-сферу. Наш исходный код доступен для просмотра на GitHub. Дизайн проекта также открыт для ознакомления в Figma.

© 2026 YeaHub

Документы

Медиа

Назад
Вопрос про JavaScript: useRef, React hooks, mutable reference, rerender, side effects

Почему useRef не вызывает ререндер при изменении значения?

Вопрос проверяет понимание работы хука useRef в React и его отличий от состояния, что важно для оптимизации производительности и управления побочными эффектами.

Короткий ответ

useRef возвращает изменяемый (mutable) объект, свойство .current которого можно менять. Изменение .current не вызывает ререндер компонента, потому что React не отслеживает изменения внутри ref-объекта для целей обновления UI. В отличие от useState, вызов setState помечает компонент как нуждающийся в ререндере. useRef предназначен для хранения значений, которые должны сохраняться между рендерами, но не влияют на визуальный вывод.

Длинный ответ

Хук useRef в React создаёт изменяемый объект, который существует на протяжении всего жизненного цикла компонента. Его основное предназначение — хранить значения, которые должны сохраняться между рендерами, но изменение которых не должно запускать повторный рендеринг компонента.

Как работает useRef

При вызове useRef(initialValue) React возвращает объект { current: initialValue }. Этот объект остаётся одним и тем же (сохраняет ссылочную идентичность) при всех последующих рендерах компонента. Вы можете читать и записывать значение в свойство .current. Поскольку React не отслеживает изменения этого объекта как зависимость для эффектов (в отличие от состояния), обновление .current не приводит к планированию нового рендера.

Сравнение с useState

  • useState: Изменение состояния через set-функцию сообщает React, что данные компонента изменились и UI可能需要 обновление. React помечает компонент как "грязный" и выполняет ререндер.
  • useRef: Объект ref — это просто контейнер для произвольного значения. React не включает его в систему реактивности. Изменение .current — это мутация обычного объекта JavaScript, которая не запускает механизмы обновления React.

Практическое применение и пример

useRef часто используется для:

  • Хранения ссылок на DOM-элементы (через атрибут ref).
  • Сохранения значений таймеров (setInterval/setTimeout).
  • Кеширования предыдущих значений или вычислений, которые не должны триггерить ререндер.
  • Хранения mutable-флагов или инстансов сторонних библиотек.
import { useRef, useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0);
  const renderCount = useRef(0); // Не вызывает ререндер
  const intervalRef = useRef(null);

  renderCount.current += 1; // Мутация! Без ререндера.

  const startTimer = () => {
    intervalRef.current = setInterval(() => {
      setCount(prev => prev + 1); // setCount вызовет ререндер
    }, 1000);
  };

  const stopTimer = () => {
    clearInterval(intervalRef.current);
  };

  return (
    
      Count: {count}
      Компонент отрендерен {renderCount.current} раз
      Старт
      Стоп
    
  );
}

В примере renderCount.current увеличивается при каждом рендере, но это не создаёт бесконечного цикла, так как изменение ref не вызывает новый рендер. Таймер хранится в intervalRef, что позволяет очистить его из любого места компонента.

Вывод

Используйте useRef, когда вам нужно хранить изменяемое значение, которое должно "переживать" рендеры компонента, но не должно влиять на его визуальное представление. Это идеально для побочных эффектов, интеграции с императивным API (например, DOM) или для избежания лишних ререндеров, когда состояние не требуется.

Уровень

  • Рейтинг:

    4

  • Сложность:

    3

Навыки

  • JavaScript

    JavaScript

  • React

    React

Ключевые слова

#useRef

#React hooks

#mutable reference

#rerender

#side effects

Подпишись на React Developer в телеграм