PassFront
  1. PassFront
  2. База знаний
  3. Рендеринг и производительность

Перерендерится ли компонент при изменении current в ref?

Рендеринг и производительность

Нет — изменение ref.current никогда не вызывает ререндер. Это документированное, намеренное свойство useRef.

Почему

Ref — обычный мутируемый объект, который React создал и отдал компоненту. В отличие от state, никаких «датчиков» на нём нет: присваивание ref.current = x — простая запись в поле объекта, о которой React не узнаёт.

const Counter = () => {
  const clicks = useRef(0);

  return (
    <button onClick={() => { clicks.current += 1; }}>
      Кликов: {clicks.current}  {/* число на экране НЕ изменится */}
    </button>
  );
};

Значение в ref честно обновляется и сохраняется, но экран покажет его только при следующем ререндере по другой причине (state, родитель, контекст).

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

  • Данные для отображения — только в state; ref — для «невидимых» значений: таймеры, инстансы, флаги, предыдущие значения.
  • Ref в зависимостях useEffect не работает: изменение current не триггерит ни рендер, ни эффект.
  • Частый паттерн «ref + state»: значение пишется в ref (без рендеров, например на каждый mousemove), а в state попадает реже (по throttle) — экран обновляется экономно.

Если рендер всё-таки нужен

Использовать state вместо ref — либо callback ref для DOM-случаев:

const [node, setNode] = useState(null);
<div ref={setNode} /> // рендер при присоединении узла — можно измерять

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

Не перерендерится: ref — мутируемый контейнер вне системы реактивности React; запись в current молчалива и синхронна. Отображаемое — в state; ref — для служебных данных. Если нужен рендер при появлении DOM-узла — callback ref + state.

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