Доброго времени суток, друзья. Продолжим обзор хуков React и в данной статье поговорим о useMemo и React.memo. Современный React проводит множество оптимизаций «под капотом». Если вашему проекту требуется дополнительная оптимизация, то хук useMemo и React.memo вам в этом помогут. Давайте рассмотрим пример их использования в функциональных компонентах.
Видео на эту тему.
Как и зачем использовать useMemo?
Хук useMemo используется для мемоизации значений. Как это работает? В функциональном компоненте у нас могут быть функции, которые производят промежуточные вычисления для получения новых знаний в компонентах. Явной иллюстрацией использования useMemo может быть именно такой «кейс».
Имеется компонент c двумя состояниями. Первое состояние по клику на текст будет менять его цвет, а второе это функция, которая по клику на кнопку, будет увеличивать счетчик на +1 и вызывать функцию sum(), в которой производится сложение входящего параметра с самим собой и как результат получится сумма этого вычисления.
Пример:
const sum = n => {
return n + n
};
const MemoComponent = () => {
const [num, setNum] = useState(1);
const [isGreen, setIsGreen] = useState(true);
const result = sum(num);
return (
<div>
<h1 onClick={() => setIsGreen(!isGreen)}
style={{ color: isGreen ? "green" : "red" }}
>
Example
</h1>
<h2>
Sum {result}
</h2>
<button onClick={() => setNum(num + 1)}>➕</button>
</div>
);
};
export default Component;
В приведенном выше примере есть небольшая проблема. Каждый раз, когда мы кликаем по тексту, происходит вызов setIsGreen, что приводит к перерендериванию компонента и, как следствие, повторный вызов функции sum(), хотя данный функционал не задействован и должен вызываться только по клику на кнопку +. Данное вычисление сейчас происходит при каждом рендере компонента, что с точки зрения оптимизации не эффективно. Для того, чтобы оптимизировать (мемоизавать) такие промежуточные вычисления требуется хук useMemo. Оборачиваем функцию sum() в useMemo и передаем вторым параметром в массиве num как зависимость, при изменении значения которой происходит повторный вызов функции sum().
Пример:
const sum = n => {
return n + n
};
const MemoComponent = () => {
const [num, setNum] = useState(1);
const [isGreen, setIsGreen] = useState(true);
const result = useMemo(() => sum(num), [num]);
return (
<div>
<h1 onClick={() => setIsGreen(!isGreen)}
style={{ color: isGreen ? "green" : "red" }}
>
Example
</h1>
<h2>
Sum {result}
</h2>
<button onClick={() => setNum(num + 1)}>➕</button>
</div>
);
};
export default MemoComponent;
Результат выполнения функции sum() был мемоизирован, теперь гораздо лучше. При изменении цвета текста не происходит повторный вызов функции sum(), а значит наша оптимизации прошла успешно.
React.memo
Для оптимизации рендеринга компонентов классов в React используется PureComponent и shouldComponentUpdate. Их альтернативой в функциональных компонентах является использование React.memo. Допустим у нас есть простой компонент, который рисует параграф текста.
Пример:
const Text = ({text}) => <p>{text}</p>
export default Text
Данный компонент является простым и не имеет состояния. Для того, чтобы React не производил лишних вычислений, а рендерил его как есть, можно обернуть его компонентом высшего порядка React.memo.
Пример:
const Text = ({text}) => <div>{text}</div>
export default React.memo(Text)
Таким образом мы говорим React использовать результаты последнего рендеринга, без создания повторного рендеринга этого компонента.
Заключение
В данной статье мы рассмотрели на примерах, как и для чего использовать useMemo для мемоизации значений и использовали компонент высшего порядка React.memo как альтернативу PureComponent в компоненте класса. Надеюсь, что данная статья была вам полезна. Учитесь, думайте, пишите код. Удачного кодинга, друзья!
Подписывайтесь на наш канал в Telegram и на YouTube для получения самой последней и актуальной информации.
Комментарии: