Когда использовать React.memo?

Прочел документацию, React.memo это PureComponent для функциональных компонентов, но почему его почти не используют ?

По логике вещей каждый компонент (без собственного состояния), даже который не использует props, должен быть обернут в memo, но так не делают, почему?

еще не могу найти однозначный ответ, буду благодарен за подсказку:
при изменении state компонента, React рендерит заново начиная с компонента у которого изменен state, или полностью все дерево с корня?
  • Вопрос задан
  • 7893 просмотра
Решения вопроса 2
Vlad_IT
@Vlad_IT
Front-end разработчик
но почему его почти не используют ?

А на основе чего такой вывод? Мне показалось наоборот, всякую оптимизацию используют везде, даже там где она делает только хуже.

(без собственного состояния)

Внутренний стейт компонента не влияет на результат работы своего memo, memo сравнивает только пропсы.

По логике вещей каждый компонент (без собственного состояния), даже который не использует props, должен быть обернут в memo, но так не делают, почему?


Тут есть условности. У меня например вот такие правила:

Оборачиваем в memo обязательно, если - родительский компонент часто перерендеривается без изменений пропсов вашего компонента. Если ваш компонент не обернуть в memo, то он будет столько же перерендериваться, сколько и родительский. Но тут я бы обернул ваш компонент в родительском в useMemo (если на хуках писать).

Не оборачиваем в memo, т.к. если обернуть, это ничего не даст или сделает хуже, если - родительский компонент перерендеривается только при изменении пропсов, которые передаются в ваш компонент. Другими словами, если ваш компонент перерендеривается из-за родителя только тогда, когда меняются значения его пропсов, то memo будет проверяться зря (а memo тоже тяжелый).

Можно обернуть в memo, если - компонент рисует сложную верстку с большим количеством других компонентов, и имеет сложный код в рендере или в useEffect (без зависимостей, который выполняется на каждый рендер).

В остальных случаях можно не использовать memo, если на то не указывают исследования производительности конкретно вашего приложения.

Еще важно следить за перерендерами, чтобы родитель не передавал пропсы, у которых на каждом рендере разная ссылка, пример:
<MemoComp onClick={() => console.warn('hello')} />
в таком случае, memo не будет работать. Это можно еще случайно пропустить, если не используете TypeScript/Flow, то вот такой код
<MemoComp isActive={item || isEnabled} />
будет перерендериваться лишний раз, если вдруг окажется, что item это объект с нестабильной ссылкой.

В общем, главное понимать, что простой memo быстрее простого рендера, нужно просто не допустить двойную работу, когда при любом рендере будет сравниваться memo и происходить рендер.
Ответ написан
alex4answ
@alex4answ Автор вопроса
Резюмируя ответы, комментарии, сторонние чтиво:

React.memo лучше использовать на компонентах, которые сложнее чем обычный вывод пропсов, где используется какая-то +- сложная логика и повторный рендер с одинаковыми props ощутимо влияет на производительность (например компоненты с построением графиков и тп)

Нет смысла мемоизировать простой компонент:
const Print = ({ text }) => <div>{text}</div>;
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы