useMemo: мемоизация значений
useMemo кеширует результат вычисления и пересчитывает его только при изменении зависимостей.
Синтаксис
const result = useMemo(() => compute(a, b), [a, b]);
Функция вызовется при первом рендере и при изменении a или b.
Зачем нужен
React перерисовывает компонент при каждом изменении стейта или пропсов. Если вычисление тяжёлое — оно будет выполняться каждый раз, даже если входные данные не менялись.
function Component({ items }: { items: Item[] }) {
const sorted = useMemo(
() => [...items].sort((a, b) => a.price - b.price),
[items]
);
return <List items={sorted} />;
}
Без useMemo сортировка выполнялась бы при каждом рендере.
Когда нужен
- Тяжёлые вычисления: сортировка, фильтрация, агрегация больших массивов
- Стабильность ссылок: объект или массив передаётся в
useEffectили в мемоизированный компонент
Когда не нужен
- Простые вычисления: сумма двух чисел, конкатенация строк
- Без стабильности ссылок: если объект не передаётся в зависимость
// Не нужно
const total = useMemo(() => a + b, [a, b]);
// Достаточно
const total = a + b;
Мемоизация сама по себе имеет стоимость: сохранение значения, сравнение зависимостей. Для простых вычислений это дороже, чем сам пересчёт.
Стабильность ссылок
function Parent() {
const filters = useMemo(() => ({ status: 'active' }), []);
return <Child filters={filters} />;
}
Без useMemo объект создаётся заново при каждом рендере, и Child перерисовывается, даже если ничего не изменилось.
Мемоизация в зависимостях
const config = useMemo(() => ({ url, method }), [url, method]);
useEffect(() => {
fetch(config.url, { method: config.method });
}, [config]);
Без useMemo объект меняется каждый рендер, и эффект сработает бесконечно.
useMemo vs useCallback
- useMemo — мемоизирует значение
- useCallback — мемоизирует функцию
const value = useMemo(() => compute(a, b), [a, b]);
const fn = useCallback(() => compute(a, b), [a, b]);
Не оптимизируй преждевременно
Не оборачивай в useMemo всё подряд. Сначала напиши просто, потом, если есть проблема производительности, добавь мемоизацию. React DevTools Profiler покажет, где узкое место.
Итоги
useMemoкеширует значение- Пересчитывает при изменении зависимостей
- Используй для тяжёлых вычислений и стабильности ссылок
- Не для простых операций
- Оптимизация — только при реальной проблеме