Вызывает ли изменение 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.