Как работает useMemo в React и зачем он нужен
useMemo — это хук в React, который позволяет мемоизировать значение, то есть сохранить результат вычислений между рендерами, чтобы не пересчитывать его заново без необходимости.
Он особенно полезен, если вычисление ресурсоёмкое или зависит от переменных, которые редко меняются.
Зачем нужен useMemo
Реакт заново вызывает компонент при каждом ререндере, и все вычисления выполняются заново, даже если результат будет тот же. Если функция тяжёлая — это снижает производительность.
Важно:
useMemo
не гарантирует кэш — он может очиститься при низком ресурсе памяти. Это подсказка для оптимизации, а не жёсткое хранилище.
Синтаксис
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
computeExpensiveValue
— функция, возвращающая результат.[a, b]
— зависимости. Если они не изменились — React вернёт кешированное значение.
Пример: без useMemo
const App = ({ items }) => {
const filtered = items.filter(item => item.active); // каждый рендер — новый фильтр
return <List data={filtered} />;
};
Каждый раз при ререндере будет вызываться filter
, даже если items
не менялись.
Пример: с useMemo
const filtered = useMemo(() => {
return items.filter(item => item.active);
}, [items]);
Теперь фильтрация произойдёт только если items
изменится, в остальном будет возвращено кешированное значение.
useMemo vs useCallback
useCallback | useMemo | |
---|---|---|
Что возвращает | Возвращает функцию | Возвращает значение |
Пример | () => | heavyComputation() |
Применение | Используется для обработчиков | Используется для значений |
Когда использовать useMemo
Хорошо использовать:
- Для ресурсоёмких вычислений (например,
sort
,filter
,map
,reduce
) - При передаче вычислённых значений в
React.memo
-компоненты - Когда
value
используется как зависимость вuseEffect
илиuseCallback
Избыточно использовать:
- В простых компонентах без тяжёлых вычислений
- Если результат всегда меняется при ререндере
Пример с тяжелой функцией
const expensiveCalculation = (num) => {
for (let i = 0; i < 1e9; i++) {}
return num * 2;
};
const App = ({ number }) => {
const result = useMemo(() => expensiveCalculation(number), [number]);
return <div>{result}</div>;
};
Без useMemo
, expensiveCalculation
будет запускаться каждый раз, даже если number
не менялся. С useMemo
— только при его изменении.
Вывод:
Используйте useMemo
, чтобы избежать повторных вычислений при ререндере, особенно если они тяжёлые или влияют на производительность.