March 28, 2021

Когда необходимо использовать React.memo и PureComponent?

Когда у вас возникнет сомнение, достаточно ли хорошо вы оптимизировали ререндер компонентов с помощью React.memo() или shouldComponentUpdate, просто помните, что Instagram плевал на ваши реакт мемы и прочие способы оптимизации ререндера (см. на рисунок статьи).

Все эти зелёные квадратики - компоненты, которые делают ререндер при нажатии на логотип инстаграма и даже при сужении окна.

Один из "страшных" снов реакт-разработчика - бесполезный ререндер компонента. Разработчик неистово пытается бороться с этой "проблемой", оборачивая с помощью React.memo() или PureComponent (shouldComponentUpdate), в надежде на то, что компонент перестанет делать ререндр, когда этого не требуется.

Согласен, делать перерисовку компонента даже тогда, когда в нём ничего не изменилось, не очень то и здорово, но и ничего страшного в этом нет 🤷🏻‍♂️

Даже если ничего не изменилось (просы, стейт), а вызов на ререндер у компонента всё равно произошёл, React не будет перерисовывать что-то в DOM-дереве, если VDOM не даст на это добро.

Дорогостоящей операцией в React является не повторный вызов компонента, а изменение чего-то в DOM-дереве.

В качестве примера, я сделал очень простую демку.

Если в компоненте "А" нажать на "+", перерисовку будут делать компонент "B" и "C", так как родительский компонент "А" был повторно вызов из-за изменения счётчика. В консоли вы увидите сообщение при каждом повторном рендере.

Но если компонент "C" обернуть с помощью React.memo, то в консоли не будет сообщение о том, что данный компонент сделал ререндер, даже если счётчик обновился.

Выглядит круто, не правда ли? Мы ведь избавились от лишнего ререндера! Ноооо

Обернув компонент "С" с помощью React.memo, мы не решили никакую проблему, а наоборот, добавили лишнюю логику, которая будет выполняться при каждом вызове компонента "С".

То есть, при изменении счётчика в компоненте "А", компонент "С" будет вызываться всё равно, но теперь ещё с дополнительной логикой проверки, которая ему в принципе была не нужна, так как он просто отображает какую-то вёрстку.

React.memo или PureComponent необходимо использовать только в том случае, если вы реально столкнулись с проблемой, которая заставляет тормозить ваш UI или выполняет лишнюю логику.

В этой статьей подробно объясняется, как происходит согласование перерисовки компонентов.