Что такое React.memo и как он работает

React.memo  —  это компонент высшего порядка React, используемый для пропуска повторных рендеров. Слово “memo” в React.memo относится к термину memoization (мемоизация).

Мемоизация  —  это метод оптимизации, используемый в основном для ускорения компьютерных программ путем хранения результатов дорогостоящих вызовов функций и возврата кэшированного результата вычислений при повторном использовании тех же входных данных.

При оборачивании компонента с помощью React.memo React будет использовать последнюю отрисованную версию этого компонента. Мемоизация используется в приложениях React для повышения производительности.

Рассмотрим на нескольких простых примерах, как работает React.memo и в каких проектах его применение будет полезным.

Начало работы

const Component1 = () => {
console.log("Component 1 rendered")
return (
<div>
<p>Component 1</p>
</div>
)
}

const Component2 = () => {
console.log("Component 2 rendered")
return (
<div>
<p>Component 2</p>
</div>
)
}

const MemoExample = () => {
const [counter, setCounter] = React.useState(0)
return (
<div>
<div>Count: {counter}</div>
<Component1 />
<Component2 />
<button onClick={() => setCounter(counter + 1)}>increase count</button>
</div>
)
}

В приведенном выше примере два компонента будут записываться в консоли при рендеринге и повторном рендеринге. Компонент MemoExample содержит Component1 и Component2, а также имеет переменную состояния counter (счетчика), при изменении которой оба компонента будут перерисовываться.

После обновления счетчика до 3 на консоли будет 4 записи для каждого компонента. Одна  —  для начального рендеринга, а остальные 3  —  для каждого изменения переменной счетчика.

Чтобы Component1 не рендерился при изменении переменной counter, можно использовать React.memo.

const Component1 = React.memo(function Component1(props) {
console.log("Component 1 rendered")
return (
<div>
<p>Component 1</p>
</div>
)
});

const Component2 = () => {
console.log("Component 2 rendered")
return (
<div>
<p>Component 2</p>
</div>
)
}

const MemoExample = () => {
const [counter, setCounter] = React.useState(0)
return (
<div>
<div>Count: {counter}</div>
<Component1 />
<Component2 />
<button onClick={() => setCounter(counter + 1)}>increase count</button>
</div>
)
}

Теперь, когда Component1 обернут React.memo, посмотрим, к чему это приведет.

Component1 оставляет только одну запись на консоли для первоначального рендеринга и ни одной записи после этого.

Свойства

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

const Component1 = React.memo(function Component1(props) {
console.log("Component 1 rendered")
return (
<div>
<p>Component 1 count: {props.count}</p>
</div>
)
});

const Component2 = () => {
console.log("Component 2 rendered")
return (
<div>
<p>Component 2</p>
</div>
)
}

const MemoExample = () => {
const [counter, setCounter] = React.useState(0)
const [counter2, setCounter2] = React.useState(0)
return (
<div>
<div>Count: {counter}</div>
<div>Count 2: {counter2}</div>
<Component1 count={counter}/>
<Component2 />
<button onClick={() => setCounter(counter + 1)}>increase count</button>
<button onClick={() => setCounter2(counter + 1)}>increase count 2</button>
</div>
)
}

В приведенный выше примере добавлены второй и начальный счетчики в качестве свойства Component1.

При увеличении значения counter должны отразиться записи на консоли для Component1. А если увеличится значение counter2, Component1 должен пропустить его рендеринг, как и раньше.

Консоль показывает 2 записи для начального рендера, еще 2 после увеличения значения counter и только 1 при увеличении counter2.

В идеале мемоизированные компоненты должны быть чистыми. Рекомендуется добавлять в такой компонент только те свойства, которые редко меняются.

Отправная точка

Чтобы попрактиковаться с React.memo, можно использовать панели приложений.

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

Применяя мемоизацию там, где можно использовать React.memo, вы сможете увеличить производительность React-приложений.

Читайте также:

Читайте нас в TelegramVK и Яндекс.Дзен


Перевод статьи Jesse Langford: What is React.memo and How Does It Work?

Предыдущая статьяТоп-10 бэкенд-фреймворков для веб-разработки в 2022 году
Следующая статьяОбнаружение и извлечение текста из изображения с помощью Python