Поиск по сайту:

Понимание React useMemo Hook


Введение

С выпуском React 16.8 появилось много полезных хуков, которые вы теперь можете использовать в своих приложениях React. Одним из встроенных хуков, представленных в версии 16.8, является useMemo. Этот хук может улучшить производительность вашего приложения.

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

Предпосылки

Для выполнения этого урока вам понадобятся:

  • Основное понимание React перед началом работы с этим руководством. Вы можете узнать больше о React, ознакомившись с серией статей How to Code in React.js.

Ссылочное равенство и дорогостоящие операции

Есть две проблемы, которые пытается решить useMemo:

  • ссылочное равенство
  • операции, требующие значительных вычислительных ресурсов

В жизненном цикле компонента React повторно отображает компонент при обновлении. Когда React проверяет любые изменения в компоненте, он может обнаружить непреднамеренное или неожиданное изменение из-за того, как JavaScript обрабатывает равенство и неглубокие сравнения. Это изменение в приложении React приведет к ненужному повторному рендерингу.

Кроме того, если этот повторный рендеринг является дорогостоящей операцией, такой как длинный цикл for, он может снизить производительность. Дорогостоящие операции могут быть затратными либо по времени, либо по памяти, либо по обработке. Помимо потенциальных технических проблем, это может привести к ухудшению работы пользователей.

Если одна часть перерисовывается, она перерисовывает все дерево компонентов.

Таким образом, React выпустил идею memo, чтобы исправить это.

Понимание мемоизации

Запоминание – это метод оптимизации, при котором сложная функция передается для запоминания. При мемоизации результат «запоминается», когда те же самые параметры передаются впоследствии.

Если у нас есть функция, вычисляющая 1 + 1, она вернет 2. Но если он использует мемоизацию, в следующий раз, когда мы пропустим через функцию 1, он не будет их суммировать; он просто запомнит ответ 2 без выполнения функции добавления.

В официальной документации React подпись useMemo выглядит так:

const memoizedValue = React.useMemo(() => computeExpensiveValue(a, b), [a, b]);

useMemo принимает функцию и массив зависимостей.

Зависимости действуют аналогично аргументам в функции. Список зависимостей — это элементы, за которыми следит useMemo: если нет изменений, результат функции останется прежним. В противном случае он повторно запустит функцию. Если они не меняются, не имеет значения, будет ли повторно отображаться весь наш компонент, функция не запустится повторно, а вместо этого вернет сохраненный результат. Это может быть оптимальным, если обернутая функция большая и дорогая. Это основное использование useMemo.

Пример создания useMemo

Вот абстрактный пример использования useMemo для массива элементов, который использует две ресурсоемкие функции:

const List = React.useMemo(() => 
  listOfItems.map(item => ({
    ...item,
    itemProp1: expensiveFunction(props.first),
    itemProp2: anotherPriceyFunction(props.second) 
  })), [listOfItems]
)

В приведенном выше примере функция useMemo будет выполняться при первом рендеринге. Это заблокировало бы поток до завершения дорогостоящих функций, так как useMemo запускается при первом рендеринге.

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

Однако при последующих рендерингах ресурсоемкие функции не нужно будет запускать снова, если listOfItems никогда не менялся. useMemo будет \запоминать возвращаемое значение каждой функции.

Это сделало бы эти дорогостоящие функции мгновенными. Это идеально, если у вас есть дорогостоящая синхронная функция или две.

Когда использовать useMemo

Сначала напишите код, а затем пересмотрите его, чтобы увидеть, сможете ли вы его оптимизировать. Если вы слишком часто реализуете useMemo в приложении, это может снизить производительность.

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

Использование правильного крючка для работы

Помимо useMemo, есть также useCallback, useRef и useEffect.

Хук useCallback похож на useMemo, но он возвращает мемоизированную функцию, а useMemo имеет функцию, которая возвращает значение.

Если ваш массив зависимостей не предоставлен, нет возможности мемоизации, и он будет вычислять новое значение при каждом рендеринге. В этом случае вы можете использовать хук useRef. Преимущество useMemo по сравнению с useRef заключается в повторном запоминании при изменении зависимостей.

Вы не захотите, чтобы useMemo отключал какие-либо побочные эффекты или любые асинхронные вызовы. В таких случаях следует использовать useEffect.

Заключение

В этой статье мы рассмотрели хук useMemo и уместно использовать его в приложении React.

useMemo может повысить производительность приложения, «запоминая» дорогостоящие функции и предотвращая повторную визуализацию каждый раз, когда в приложении происходят изменения.

Хотя производительность может быть улучшена с помощью этого хука, он также может замедлить работу вашего приложения, если вы будете им злоупотреблять. Чем больше вы используете хук, тем больше памяти должно выделять ваше приложение.

Чтобы узнать больше о лучших практиках React, следуйте полной серии How To Code in React.js на DigitalOcean.