useMemo 是 React 中的一个 Hook,用于缓存(记忆)计算结果,避免在每次组件重新渲染时都重复执行开销较大的计算逻辑。
作用
- 性能优化 :当某个值的计算成本较高(比如遍历大数组、复杂运算等),且该值只在某些依赖项变化时才需要重新计算,就可以用
useMemo将其缓存起来。 - 避免不必要的重复计算:只要依赖项没有变化,就直接返回之前缓存的值。
语法
js
const memoizedValue = useMemo(() => {
// 计算逻辑
return computedValue;
}, [dependencies]);
- 第一个参数是一个函数,返回要缓存的值。
- 第二个参数是一个依赖数组。只有当数组中的某个依赖项发生变化时,才会重新执行计算函数。
举个例子 🌰
假设我们有一个输入框,用户输入一个数字 n,我们要计算从 1 到 n 的所有偶数之和。这个计算如果 n 很大,会比较耗时。
js
import React, { useState, useMemo } from 'react';
function ExpensiveComponent() {
const [count, setCount] = useState(0);
const [inputValue, setInputValue] = useState('');
// 模拟一个昂贵的计算:计算 1 到 count 中所有偶数的和
const expensiveValue = useMemo(() => {
console.log('正在计算...');
let sum = 0;
for (let i = 1; i <= count; i++) {
if (i % 2 === 0) sum += i;
}
return sum;
}, [count]); // 只有 count 变化时才重新计算
return (
<div>
<p>偶数之和: {expensiveValue}</p>
<button onClick={() => setCount(c => c + 1)}>增加 count</button>
{/* 这个输入不会触发 expensiveValue 重新计算 */}
<input
value={inputValue}
onChange={e => setInputValue(e.target.value)}
placeholder="随便输点啥"
/>
</div>
);
}
说明:
- 当你修改输入框内容(
inputValue)时,组件会重新渲染,但由于useMemo的依赖项[count]没变,所以 不会重新执行计算逻辑 ,console.log('正在计算...')不会打印。 - 只有点击按钮改变
count时,才会重新计算。
注意事项
- 不要滥用 :如果计算本身不耗时,使用
useMemo反而会增加内存开销和代码复杂度。 useMemo不能保证 缓存一定有效(React 在内存紧张时可能会丢弃缓存),所以你的代码即使不用useMemo也应该能正常工作。- 和
useCallback的区别:useCallback(fn, deps)相当于useMemo(() => fn, deps),主要用于缓存函数。