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

Какие проблемы решает useMemo?

Хуки

useMemo решает две разные проблемы: дорогие повторные вычисления и нестабильные ссылки.

Проблема 1: пересчёт на каждом рендере

Тело компонента выполняется при каждом рендере — вместе с ним и тяжёлые вычисления, даже если исходные данные не менялись:

const Report = ({ rows, filter }) => {
  // без useMemo: сортировка 10 000 строк на КАЖДЫЙ рендер,
  // включая ввод в несвязанное поле
  const sorted = useMemo(
    () => [...rows].filter((r) => r.type === filter).sort(byDate),
    [rows, filter],
  );
};

Выигрыш реален только когда вычисление действительно дорогое: для a + b useMemo вреден (сравнение deps дороже).

Проблема 2: новая ссылка каждый рендер

Объекты и массивы, создаваемые в рендере, каждый раз новые. Это ломает всё, что сравнивает по ссылке:

const config = useMemo(() => ({ pageSize: 20 }), []);

<Table config={config} />           // React.memo(Table) теперь работает
useEffect(() => load(config), [config]); // эффект не перезапускается каждый рендер

Здесь useMemo нужен не ради скорости вычисления (объект создаётся мгновенно), а ради стабильности ссылки для memo-детей и зависимостей хуков.

Чего useMemo не решает

Не убирает сам ререндер компонента (это React.memo), не гарантирует однократное выполнение (React вправе сбросить кеш), не место для побочных эффектов. И не нужен там, где вычисление дёшево — лишняя сложность.

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

useMemo решает: (1) повторные дорогие вычисления — результат кешируется до изменения deps; (2) нестабильные ссылки на объекты/массивы — чтобы не ломать React.memo у детей и зависимости эффектов. Не убирает ререндер, не гарантирует однократность и не нужен для дешёвых вычислений.

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