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

В чем разница между useMemo и useCallback?

Хуки

Оба хука мемоизируют, но разные вещи: useMemo — результат вызова функции, useCallback — саму функцию.

Главное отличие

// useMemo: функция ВЫЗЫВАЕТСЯ, кешируется её результат
const total = useMemo(() => calcTotal(items), [items]);

// useCallback: функция НЕ вызывается, кешируется её ссылка
const handleAdd = useCallback(() => addItem(item), [item]);

Формально useCallback(fn, deps) эквивалентен useMemo(() => fn, deps).

Когда что использовать

  • useMemo — дорогое вычисление (фильтрация, сортировка, агрегация) или создание объекта/массива, который должен сохранять ссылку между рендерами.
  • useCallback — функция, которая передаётся пропом в мемоизированный дочерний компонент или стоит в зависимостях другого хука.

Пример вместе

const ProductList = ({ products, onBuy }) => {
  const sorted = useMemo(
    () => [...products].sort((a, b) => a.price - b.price),
    [products],
  );

  const handleBuy = useCallback((id) => onBuy(id), [onBuy]);

  return sorted.map((p) => (
    <ProductCard key={p.id} product={p} onBuy={handleBuy} />
  ));
};

Нюансы

  • Оба сравнивают зависимости поверхностно (Object.is) и оба — оптимизация, а не средство корректности.
  • Ошибка в зависимостях у обоих даёт устаревшие значения (stale closure).

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

useMemo вызывает функцию и кеширует её результат (значение), useCallback кеширует саму функцию (ссылку). useMemo — про дорогие вычисления и стабильные объекты, useCallback — про стабильные колбэки для дочерних компонентов и зависимостей хуков.

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