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

Как происходит сравнение props в React?

Компоненты

Сравнение props в React происходит в двух разных местах, и работает по-разному: при диффе DOM-элементов (всегда) и при решении «рендерить ли компонент» (только если он мемоизирован).

По умолчанию: props компонентов НЕ сравниваются

Обычный компонент перерендеривается вместе с родителем без всякой проверки props. Распространённое заблуждение — «React сравнил props и решил обновить»; на деле решение «рендерить» каскадное, а сравнение включается только у React.memo/PureComponent.

React.memo: поверхностное сравнение

const Card = React.memo(CardInner);

При рендере родителя React сравнивает каждый проп старого и нового набора через Object.is:

  • примитивы — по значению;
  • объекты, массивы, функции — по ссылке: {a: 1} !== {a: 1}.

Отсюда правило: инлайн-объекты/функции/JSX-children ломают memo — ссылки каждый рендер новые. Кастомное сравнение — вторым аргументом memo: React.memo(Comp, (prev, next) => boolean).

DOM-элементы: дифф атрибутов

Для host-элементов (div, input) reconciliation сравнивает старые и новые props, чтобы вычислить минимальные правки атрибутов/стилей — это происходит всегда, но влияет на объём DOM-операций, а не на вызов компонентов.

Где ещё то же сравнение

Object.is используется и в зависимостях useEffect/useMemo/useCallback, и при проверке «то же ли значение передали в сеттер». Единая механика: ссылочное равенство, глубоких сравнений React не делает никогда (дорого).

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

По умолчанию props не сравниваются — дети рендерятся каскадом. Сравнение включает React.memo: поверхностное, каждый проп через Object.is (объекты/функции — по ссылке, поэтому нужны useMemo/useCallback). Глубокого сравнения в React нет нигде; для DOM-узлов дифф props определяет минимальные правки атрибутов.

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