在 React 中,useMemo 和 memo 都用于 优化性能,减少不必要的渲染,但它们的使用场景不同。
1. useMemo(记忆化计算)
📌 作用
- 缓存计算结果,避免每次渲染都重新计算
- 只有当 依赖项 发生变化时,才会重新计算
✅ 适用场景
- 计算量较大的值(避免重复计算)
- 避免子组件不必要的渲染(与
useCallback结合使用)
💡 代码示例
import React, { useState, useMemo } from "react";
const ExpensiveCalculation = ({ num }: { num: number }) => {
const result = useMemo(() => {
console.log("计算中...");
return num * 2; // 假设这是一个昂贵的计算
}, [num]);
return <p>计算结果: {result}</p>;
};
export default function App() {
const [count, setCount] = useState(0);
const [num, setNum] = useState(5);
return (
<div>
<button onClick={() => setCount(count + 1)}>增加 count</button>
<button onClick={() => setNum(num + 1)}>增加 num</button>
<p>count: {count}</p>
<ExpensiveCalculation num={num} />
</div>
);
}
useMemo缓存计算结果,当num变化时才重新计算- 点击
count按钮时,num没变,因此不会重新计算
2. memo(组件缓存)
📌 作用
- 缓存组件,如果 props 没变,则不会重新渲染
✅ 适用场景
- 组件 性能优化,防止不必要的渲染
- 适用于 功能组件(Functional Component)
💡 代码示例
import React, { useState, memo } from "react";
const Child = memo(({ name }: { name: string }) => {
console.log("子组件渲染...");
return <p>子组件: {name}</p>;
});
export default function App() {
const [count, setCount] = useState(0);
const [name, setName] = useState("React");
return (
<div>
<button onClick={() => setCount(count + 1)}>增加 count</button>
<button onClick={() => setName("React " + Math.random())}>改变 name</button>
<p>count: {count}</p>
<Child name={name} />
</div>
);
}
Child组件使用memo进行缓存- 点击
count按钮时,name没变,所以Child不会重新渲染 - 点击
name按钮时,Child才会重新渲染
3. useMemo vs memo 的区别
useMemo
作用: 记忆化 计算值
优化点: 避免重复计算
依赖项: useMemo(fn, [deps])
适用场景: 计算量大的数据处理
返回值: 计算结果
memo
作用: 记忆化 组件
优化点: 避免组件不必要的渲染
依赖项: 组件的 props
适用场景: 组件的性能优化
返回值: 缓存组件
4. useMemo 和 memo 结合使用
可以 同时使用 useMemo 和 memo 来优化 React 组件。
💡 示例
import React, { useState, useMemo, memo } from "react";
const Child = memo(({ num }: { num: number }) => {
const result = useMemo(() => {
console.log("计算 num * 2...");
return num * 2;
}, [num]);
console.log("子组件渲染...");
return <p>计算结果: {result}</p>;
});
export default function App() {
const [count, setCount] = useState(0);
const [num, setNum] = useState(5);
return (
<div>
<button onClick={() => setCount(count + 1)}>增加 count</button>
<button onClick={() => setNum(num + 1)}>增加 num</button>
<p>count: {count}</p>
<Child num={num} />
</div>
);
}
memo防止Child组件无意义渲染useMemo缓存num * 2的计算值- 点击
count按钮时,Child不会重新渲染 - 点击
num按钮时,Child重新渲染并重新计算
总结
useMemo适用于避免重复计算memo适用于避免子组件不必要的渲染- 两者可以结合使用来优化 React 性能