useMemo
是 React 提供的一个 性能优化 Hook,它用来缓存计算结果,避免在每次组件渲染时重复执行开销较大的计算。通俗点说,它是一个“记忆函数返回值”的工具。
1. 基本用法
import React, { useMemo, useState } from 'react';
function Demo() {
const [count, setCount] = useState(0);
const [text, setText] = useState('');
// 计算量比较大的函数
const expensiveCalculation = (num: number) => {
console.log('执行了昂贵计算...');
let total = 0;
for (let i = 0; i < 100000000; i++) {
total += i;
}
return total + num;
};
// 使用 useMemo 缓存计算结果
const result = useMemo(() => {
return expensiveCalculation(count);
}, [count]); // 依赖 count 改变时才重新计算
return (
<div>
<p>计算结果: {result}</p>
<button onClick={() => setCount(count + 1)}>加1</button>
<input value={text} onChange={(e) => setText(e.target.value)} />
</div>
);
}
输出说明:
- 没有
useMemo
时:每次输入框输入文字,组件都会重新渲染,昂贵计算也会执行一次,性能浪费。 - 使用
useMemo
后:只有count
变化时才执行昂贵计算,输入框输入文字不会触发重新计算。
2. 语法
const memoizedValue = useMemo(() => {
// 这里执行计算逻辑
return 计算结果;
}, [依赖项1, 依赖项2]);
- 返回值:
useMemo
返回回调函数的执行结果。 依赖数组:
- 如果依赖项没变,返回缓存的值。
- 如果依赖项发生变化,重新执行回调并更新缓存。
3. 常见应用场景
避免重复执行复杂计算
比如数据过滤、排序、大循环计算。避免子组件无意义渲染
当你将对象或数组作为props
传递给子组件时,可以用useMemo
保证它的引用不变:
const data = useMemo(() => ({ value: count }), [count]);
<Child data={data} />
否则每次父组件渲染,都会生成新的对象引用,导致 Child
误以为 props
变化,从而重新渲染。
4. 注意事项
不要滥用:
如果计算开销很小,用useMemo
反而有额外性能消耗(创建闭包、依赖比对)。和 useCallback 区别:
useMemo
缓存的是值。useCallback
缓存的是函数。
依赖必须正确:
如果忘记填依赖项,可能导致数据不同步或缓存错误。