useMemo 是 React 提供的一个 性能优化 Hook,它用来缓存计算结果,避免在每次组件渲染时重复执行开销较大的计算。通俗点说,它是一个“记忆函数返回值”的工具。
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 变化时才执行昂贵计算,输入框输入文字不会触发重新计算。const memoizedValue = useMemo(() => {
// 这里执行计算逻辑
return 计算结果;
}, [依赖项1, 依赖项2]);
useMemo 返回回调函数的执行结果。依赖数组:
避免重复执行复杂计算
比如数据过滤、排序、大循环计算。
避免子组件无意义渲染
当你将对象或数组作为 props 传递给子组件时,可以用 useMemo 保证它的引用不变:
const data = useMemo(() => ({ value: count }), [count]);
<Child data={data} />
否则每次父组件渲染,都会生成新的对象引用,导致 Child 误以为 props 变化,从而重新渲染。
不要滥用:
如果计算开销很小,用 useMemo 反而有额外性能消耗(创建闭包、依赖比对)。
和 useCallback 区别:
useMemo 缓存的是值。useCallback 缓存的是函数。依赖必须正确:
如果忘记填依赖项,可能导致数据不同步或缓存错误。