PassFront
  1. PassFront
  2. База знаний
  3. Хуки

В чем проблема использования useCallback, useMemo, React memo?

Хуки

У инструментов мемоизации есть цена и набор ловушек — «оптимизация» нередко оказывается вредом.

Проблема 1: это не бесплатно

Каждый useMemo/useCallback хранит прошлые значения и сравнивает зависимости на каждом рендере; React.memo сравнивает все props. Если рендер дешёвый или props всё равно меняются — накладные расходы без выигрыша: больше памяти, больше работы, медленнее, чем без мемоизации.

Проблема 2: молчаливые поломки

Мемоизация — цепочка, рвущаяся от одного звена:

<MemoList
  onSelect={stableCallback}  // useCallback — ок
  options={{ pageSize: 20 }} // новый объект каждый рендер — memo сломан
/>

Инлайн-объекты, children (JSX — новые объекты), новый колбэк без useCallback — и React.memo продолжает рендерить, не сообщая об этом. Код выглядит оптимизированным, но не работает; выявляется только профайлером.

Проблема 3: баги через зависимости

Неполные deps ради «стабильности» → устаревшие замыкания: обработчик видит старый state, данные не обновляются. Это уже не про скорость — про корректность. Плюс ложная уверенность: useMemo — подсказка, а не гарантия (React вправе сбросить кеш) — на нём нельзя строить логику «выполнится ровно один раз».

Проблема 4: стоимость для людей

Код обрастает обёртками, каждое изменение требует пересмотра зависимостей, ревью усложняется. Хрупкость: один рефакторинг («вынесу объект в рендер») незаметно ломает оптимизацию всего поддерева.

Как правильно

Мемоизировать по результатам профилирования, а не по привычке; сначала архитектура (спуск состояния, children-как-проп, разделение контекстов). React Compiler (React 19) автоматизирует мемоизацию — признание, что ручной подход был проблемой.

Коротко для собеседования

Проблемы: накладные расходы на сравнение/хранение при дешёвых рендерах; молчаливые поломки цепочки от одного нестабильного пропа (включая children); stale-баги из-за неполных зависимостей; useMemo — не гарантия, а подсказка; усложнение и хрупкость кода. Поэтому — точечно по профайлеру, а не везде; React Compiler снимает вопрос.

Другие вопросы раздела