РЕДАКТИРОВАТЬ: Я больше не поддерживаю мнение этого поста, но технические проблемы, из-за которых PureComponent часто не может предотвратить рендеринг, по-прежнему заслуживают понимания.
Потраченные впустую рендеры - большая проблема для работоспособного кода React.js. Основная команда React предложила решение: React.PureComponent. Давайте посмотрим, как это работает, какие проблемы решает, а какие не решает.
Итак, что это такое? PureComponent в точности похож на React.Component с одним отличием: он реализует shouldComponentUpdate. Это позволяет предотвратить рендеринг на основе некоторой эвристики. PureComponent реализует это как поверхностную проверку равенства новых свойств и старых свойств, а также для состояния. Итак, если у вас есть реквизиты «a» и «b», он, по сути, делает следующее:
Теоретически это замечательно, потому что мы можем предотвратить дорогостоящий рендеринг, значительно улучшив нашу производительность. Но ждать! «Это слишком хорошо, чтобы быть правдой», - слышу я. Что ж ... ты прав. Мы сталкиваемся с проблемами из-за этих! == проверок. Допустим, Foo - это компонент, расширяющий React.PureComponent. Вот несколько примеров использования Foo:
У этих трех примеров одна и та же проблема: Foo всегда будет выполнять повторную визуализацию, потому что shouldComponentUpdate всегда возвращает true! В первых двух, shouldComponentUpdate проверяет, если this.props.x! == nextProps.x, и, поскольку {}! == {}, и аналогично для .map, он всегда будет видеть, что реквизиты изменились. То же самое происходит с опорой children, где this.props.children! == nextProps.children.
Незначительная проблема здесь в том, что мы выполняем проверку shouldComponentUpdate без усиления, что дороже, чем пример, который я привел выше, потому что он должен перебирать ключи как текущего, так и следующего объекта props.
Более серьезная проблема заключается в том, что мы предполагаем, что решили проблему с производительностью, но в большинстве случаев лишь немного ухудшали ее.
Хм… так как же нам избежать ненужных рендеров и различий? Трюк! Введите: реагировать-обновлять-если-изменено.
В этом примере Foo использует response-update-if-changed вместо PureComponent. Вместо того, чтобы проверять, является ли this.props.children! == nextProps.children, он просто проверяет свойство updateIfChanged на равенство. Одна проверка на равенство; это оно.
Остались две проблемы.
- У нас может быть несколько значений, которые могут изменяться, или одно значение, которое следует сравнивать на основе глубокого равенства. В этой ситуации вы можете использовать опору updateIfChangedEqual = {[a, b]}.
- Нам все еще нужно вычислить ‹h1› в приведенном выше примере (но не различать его), что на самом деле может быть дорогостоящим для вычисления. См. Компонент UpdateIfChanged в response-update-if-changed, который решает эту проблему.
React.PureComponent редко бывает полезным, но не теряйте надежды на отличную производительность в React.js!
Хакерский полдень - это то, с чего хакеры начинают свои дни. Мы часть семьи @AMI. Сейчас мы принимаем заявки и рады обсудить рекламные и спонсорские возможности.
Чтобы узнать больше, прочтите нашу страницу о нас, поставьте лайк / напишите нам в Facebook или просто tweet / DM @HackerNoon.
Если вам понравился этот рассказ, мы рекомендуем прочитать наши Последние технические истории и Современные технические истории. До следующего раза не воспринимайте реалии мира как должное!