PassFront
  1. PassFront
  2. База знаний
  3. Хуки

Вызывает ли изменение useRef перерисовку компонента?

Хуки

Нет. Запись в ref.current не вызывает перерисовку — в этом и смысл useRef: хранить данные между рендерами, не трогая рендеринг.

Почему

React узнаёт о необходимости рендера только через свои механизмы: сеттеры state, dispatch, изменение контекста, подписки. Ref — обычный мутируемый объект { current }, который React отдал компоненту и больше не отслеживает: записали значение — оно просто лежит.

const Demo = () => {
  const countRef = useRef(0);

  const handleClick = () => {
    countRef.current += 1;         // ничего не произойдёт на экране
    console.log(countRef.current); // но значение сохранено
  };

  return (
    <>
      <button onClick={handleClick}>+1</button>
      <span>{countRef.current}</span> {/* НЕ обновится при клике */}
    </>
  );
};

Экран обновится лишь когда компонент перерендерится по другой причине — тогда JSX прочитает актуальный ref.current.

Практические следствия

  • Не хранить в ref то, что должно отображаться — для этого state. Ref — для таймеров, инстансов, флагов, DOM-узлов.
  • Не читать/писать ref во время рендера (кроме ленивой инициализации) — рендер должен быть чистым; место для работы с ref — эффекты и обработчики.
  • Если нужен рендер при присоединении DOM-узла — используют callback ref (функцию в атрибуте ref) вместе с setState.

Сравнение с state

setState(v) — уведомляет React, асинхронно, вызывает рендер. ref.current = v — молча, синхронно, без рендера.

Коротко для собеседования

Изменение ref.current перерисовку не вызывает: React ref не отслеживает — это просто мутируемый контейнер. Новое значение появится на экране только при следующем рендере по другой причине. Отображаемые данные — в state; ref — для служебных значений и DOM.

Другие вопросы раздела