Что вызывает перерендер компонента?
Рендеринг и производительность
Компонент перерендеривается в четырёх случаях: изменился его state, перерендерился родитель, изменился потребляемый контекст, или обновился хук с подпиской (стор). Изменение props само по себе — следствие рендера родителя.
Причины подробно
- Собственный state — вызов сеттера useState/useReducer с новым значением (по
Object.is). Если значение то же — рендер пропускается. - Рендер родителя — по умолчанию React рекурсивно рендерит всё поддерево, даже если props ребёнка не менялись. Останавливается это только
React.memo. - Контекст — изменение value у
Context.Providerперерендеривает всех потребителей (useContext), причём React.memo от этого не спасает. - Внешние сторы — хуки вроде
useSelector(Redux),useSyncExternalStoreтриггерят рендер при изменении выбранных данных.
Чего НЕ вызывает перерендер
- Изменение
ref.current. - Мутация объекта в state без создания новой ссылки (React её не видит).
- Вызов сеттера с тем же значением.
Пример каскада
const App = () => {
const [time, setTime] = useState(Date.now());
// каждый тик перерендерит и Header, и Feed — им props не нужны
return (
<>
<Header />
<Feed />
<Clock time={time} />
</>
);
};Лечится спуском состояния в Clock или мемоизацией соседей.
Как диагностировать
React DevTools Profiler показывает, какие компоненты рендерились и почему (галочка «Record why each component rendered»).
Коротко для собеседования
Перерендер вызывают: обновление собственного state, рендер родителя (каскадом вниз), изменение контекста и подписки на внешние сторы. «Изменение props» — не самостоятельная причина, а следствие рендера родителя. Ref и мутации без новой ссылки перерендер не вызывают.