Мемоизация компонента React

Мемоизация — это функция в React. Библиотека сравнивает (неглубоко) две версии объекта и, если они одинаковы, не перерисовывает (или перекомпилирует) его, создавая оптимизацию производительности и памяти.

React.memo более высокого порядка (заметьте, не useMemo), используемый на компоненте, очень легко реализовать, но это не всегда эффективно или необходимо. Как и все, что касается мемоизации в React, мы не должны мемоизировать все подряд, а только те объекты, которые тяжелые, большие или очень часто пересматриваются.

Так в моей работе произошел интересный случай. У меня был довольно большой родительский компонент, который оборачивается внутри меньших дочерних компонентов. Я просто изменю тип объектов и имя компонента, но пример я привожу тот же, что и раньше.

Как мы мемоизируем компонент?

Предположим, у нас есть:

  const BigComponent = ({...lots of props}) => {...lots of stuff done}
Войти в полноэкранный режим Выйти из полноэкранного режима

тогда мы просто ставим memo на экспорт

  export default memo(BigComponent)
Войти в полноэкранный режим Выйти из полноэкранного режима

Достаточно ли этого? Иногда да. Но интереснее другое. Как React узнает, что сравнивать? Он берет предыдущую версию и следующую версию (ту, которую мы обновляем новыми реквизитами). Точно так же memo может использовать эти две версии в качестве аргументов обратного вызова. Они могут быть проверены для более быстрого сравнения, что еще больше ускоряет процесс мемоизации.

Предположим, что наш BigComponent в основном управляет карточкой школьника, и у нас есть дочерние компоненты, отображаемые в соответствии с учеником. Тогда у нас будет BigComponent, предположительно изменяющийся при изменении id ученика (предположим, что он отображается из родительского компонента).

  const BigComponent = ({student, ...other props}) => {...lots of stuff done}
Вход в полноэкранный режим Выход из полноэкранного режима

Теперь мы можем мемоизировать компонент, сравнивая идентификаторы учеников. Мы можем считать идентификаторы ключами объекта. Если они одинаковы, компонент останется прежним, в противном случае он будет перерендерирован.

Но, как вы видите, я сделал это немного по-другому!

  export default memo(BigComponent, (prev, next) => prev.student.id !== next.student.id)
Вход в полноэкранный режим Выйти из полноэкранного режима

Здесь будет сказано: если предыдущий ID отличается от следующего, верните true. Проблема здесь в том, что мы получаем реквизиты и используем их на дочернем компоненте, поэтому если ID одинаковые (===), то это ничего не даст (не откроет карточку).

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

Итак, подведем итог: мы мемоизируем (а не рендерим) этот компонент наоборот, только когда ID (ключи) меняются. Это означает, что когда мы открываем карточку студента, она будет перезагружаться. Но когда мы добавляем больше студентов или используем другие карточки студентов, они не будут рендериться на странице, и мы получим улучшение производительности.

Оцените статью
devanswers.ru
Добавить комментарий