> Как использовать memo в React для предотвращения лишних рендеров (React)

Уровень: senior · Роль: frontend · Категория: Технические вопросы

Компании: Centicore

Стек: React

> Пример ответа

Короткий ответ

React.memo - это higher-order component, который предотвращает повторный рендер компонента, если его props не изменились (поверхностное сравнение). Используется для оптимизации производительности, когда компонент часто перерисовывается с одними и теми же props. Важно применять только к чистым компонентам без side effects и не злоупотреблять, так как само сравнение имеет стоимость.

Подробное объяснение

React.memo работает путём кэширования результата рендера компонента. При каждом обновлении родителя React выполняет поверхностное сравнение (shallow comparison) предыдущих и новых props. Если они равны, React переиспользует закешированный результат, пропуская рендер компонента.

Механизм сравнения можно кастомизировать через второй аргумент - функцию areEqual(prevProps, nextProps), возвращающую true если props равны.

Важно понимать, что React.memo не влияет на состояние или контекст - если компонент использует useState, useReducer или useContext, он всё равно будет перерендериваться при их изменении.

Ключевые случаи для применения:

  • Компоненты, которые рендерятся часто (например, в списках)
  • Компоненты с тяжёлыми вычислениями
  • Компоненты, которые не зависят от часто меняющихся данных

На практике

Применять React.memo стоит после профилирования и выявления узких мест. Типичный сценарий - оптимизация списков с key и стабильными ссылками на props. Важно помнить, что если передавать в props объекты, функции или массивы без useMemo/useCallback, React.memo будет бесполезен - каждое создание новой ссылки приведёт к перерендеру.

Хорошая практика - оборачивать в React.memo компоненты, которые:

  • Являются листьями дерева компонентов
  • Имеют стабильные props (примитивы или мемоизированные значения)
  • Используются в циклических рендерах (списки, таблицы)

Пример кода

JSX
import React, { memo, useState, useCallback } from 'react';
// Компонент, обёрнутый в memo
const ExpensiveItem = memo(({ title, onSelect }) => {
console.log('ExpensiveItem render:', title);
return (
<div onClick={() => onSelect(title)}>
{title}
</div>
);
});
// Родительский компонент
function List() {
const [items, setItems] = useState(['a', 'b', 'c']);
const [count, setCount] = useState(0);
// Стабильная ссылка на callback
const handleSelect = useCallback((title) => {
console.log('Selected:', title);
}, []);
return (
<div>
<button onClick={() => setCount(c => c + 1)}>
Count: {count}
</button>
{items.map(item => (
<ExpensiveItem
key={item}
title={item}
onSelect={handleSelect}
/>
))}
</div>
);
}

Как отвечать на собеседовании

Начни с определения и цели React.memo. Объясни механизм поверхностного сравнения и когда это действительно нужно. Покажи понимание trade-off: сравнение props имеет стоимость, поэтому React.memo не панацея. Упомяни связь с useMemo и useCallback для стабильных ссылок. Приведи пример из практики - оптимизация списка с тысячей элементов. Подчеркни, что преждевременная оптимизация вредна, и нужно профилировать.

Что проверяет интервьюер

  • Понимание механизма рендеринга React и виртуального DOM
  • Знание разницы между React.memo, useMemo и useCallback
  • Умение оценивать необходимость оптимизации
  • Понимание поверхностного сравнения и его ограничений
  • Знание, что React.memo не работает с контекстом и состоянием
  • Способность объяснить trade-off между производительностью и читаемостью

Типичные ошибки

  • Оборачивание всех компонентов подряд без профилирования
  • Передача анонимных функций или объектов как props (ломает мемоизацию)
  • Использование React.memo с компонентами, имеющими side effects в рендере
  • Забывание про key при рендере списков
  • Ожидание, что React.memo предотвратит рендер при изменении контекста
  • Использование кастомной areEqual без понимания её влияния на производительность

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью