PassFront
  1. PassFront
  2. База знаний
  3. Компоненты

Как компонент понимает, перерисовались ли пропсы?

Компоненты

Обычный компонент никак не понимает — по умолчанию React не сравнивает props: ребёнок перерисовывается просто потому, что перерисовался родитель.

Поведение по умолчанию

const Child = ({ title }) => <h1>{title}</h1>;
// рендерится при каждом рендере родителя, даже если title тот же

Сравнивать props у каждого узла дороже, чем повторно вызвать лёгкую функцию, — React этого не делает. Проверка «изменились ли props» включается только при явной мемоизации.

Когда сравнение происходит

React.memo — обёртка добавляет проверку: поверхностное сравнение каждого пропа через Object.is (примитивы по значению, объекты/функции по ссылке).

const Child = React.memo(ChildInner);
// теперь: props равны → рендер пропускается

Второй аргумент memo — своя функция (prev, next) => boolean (true = «равны, не рендерить»). В классах то же делают PureComponent и shouldComponentUpdate.

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

  • Инлайн-объекты и функции (style={{}}, onClick={() => ...}) — новые ссылки, memo не сработает; нужны useMemo/useCallback у родителя.
  • children — тоже проп, и JSX-дети создаются заново каждый рендер.
  • Глубокого сравнения React не делает нигде: мутация внутри объекта props «невидима».

Как узнать, что изменилось (отладка)

React DevTools Profiler с опцией «Record why each component rendered» показывает, какой именно проп изменился; вручную — сравнить prev/next через useRef.

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

Без React.memo компонент props не сравнивает — он рендерится каскадом вместе с родителем. С memo (или PureComponent) идёт поверхностное сравнение по Object.is: объекты и функции по ссылке, поэтому инлайн-props ломают проверку. Причины рендера показывает Profiler.

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