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

Когда в React ререндерится компонент?

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

Компонент ререндерится в четырёх случаях: свой state изменился, отрендерился родитель, изменился контекст, сработала подписка на внешний стор.

Полный список триггеров

  • Собственный state: сеттер useState / dispatch useReducer с новым (по Object.is) значением. То же значение → ререндер пропускается.
  • Родитель отрендерился: React рекурсивно рендерит поддерево — дети обновляются независимо от props. Изменение props как таковое не отслеживается: оно всегда следствие рендера родителя. Прерывает каскад только React.memo (и то при стабильных props).
  • Контекст: изменение value у провайдера ререндеривает всех потребителей useContext — React.memo не спасает.
  • Внешние подписки: useSelector, useSyncExternalStore, хуки React Query — при изменении выбранных данных.

Не вызывают ререндер

  • Запись в ref.current.
  • Мутация state-объекта без сеттера/новой ссылки.
  • Сеттер с тем же значением.
  • Изменение обычной переменной (не state).

Мини-демонстрация

const Parent = () => {
  const [n, setN] = useState(0);
  return (
    <>
      <button onClick={() => setN(n + 1)}>+</button>
      <Child />            {/* ререндер при каждом клике: родитель отрендерился */}
      <MemoChild />        {/* НЕ ререндерится: memo + props не менялись */}
    </>
  );
};

Уточнение

Ререндер — вызов функции компонента, не обязательно изменение DOM: после рендера дифф может не найти отличий. Диагностика частых ререндеров — React DevTools Profiler («why did this render»).

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

Триггеры: свой state (Object.is-проверка), рендер родителя (каскад, независимо от props; стопится React.memo), изменение контекста, подписки на сторы. Ref, мутации и «то же значение» рендер не вызывают. Ререндер ≠ обновление DOM.

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