Когда в 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.