useMemo
是 React 中用于性能优化的 Hook,它通过缓存计算结果,避免在组件重新渲染时重复执行昂贵的计算。但并非所有场景都需要使用,过度使用反而会增加内存开销。以下是适合使用 useMemo
的典型场景:
如果组件中存在耗时的计算(如大数据量排序、复杂数据转换、高频次数学运算等),且这些计算在组件重新渲染时会被重复执行,此时 useMemo
能显著提升性能。
示例:对大型数组进行排序
import { useMemo, useState } from 'react';
function BigList({ items }) {
// 对大数组排序是昂贵操作,用 useMemo 缓存结果
const sortedItems = useMemo(() => {
console.log('执行排序(仅当 items 变化时)');
return [...items].sort((a, b) => a.value - b.value); // 假设 items 是大型数组
}, [items]); // 仅当 items 变化时重新计算
return (
<ul>
{sortedItems.map(item => (
<li key={item.id}>{item.name}</li>
))}
</ul>
);
}
如果不使用 useMemo
,每次组件重新渲染(即使 items
没变)都会执行排序,造成性能浪费。
如果计算结果会作为 props
传递给子组件,且子组件是「纯组件」(如使用 React.memo
包装),此时用 useMemo
缓存结果可以避免子组件不必要的重渲染。
示例:避免子组件无效重渲染
import { useMemo, useState, memo } from 'react';
// 子组件:用 React.memo 包装(仅在 props 变化时重渲染)
const ExpensiveChild = memo(({ data }) => {
console.log('子组件渲染');
return <div>{data.name}</div>;
});
function Parent() {
const [count, setCount] = useState(0);
const rawData = { id: 1, value: 100 };
// 计算结果作为子组件 props,用 useMemo 缓存
const processedData = useMemo(() => {
return { ...rawData, name: `处理后的数据: ${rawData.value}` };
}, [rawData]); // 仅当 rawData 变化时重新计算
return (
<div>
<button onClick={() => setCount(count + 1)}>计数: {count}</button>
<ExpensiveChild data={processedData} />
</div>
);
}
useMemo
,每次 Parent
因 count
变化重渲染时,processedData
会被重新创建(引用变化),导致 ExpensiveChild
也跟着重渲染(即使数据内容没变)。useMemo
后,processedData
引用不变,ExpensiveChild
不会无效重渲染。如果计算逻辑依赖多个变量,且这些变量频繁变化,但计算结果可能频繁重复(如根据多个筛选条件过滤列表),useMemo
可以避免重复计算相同结果。
示例:多条件筛选数据
const filteredList = useMemo(() => {
return list.filter(item => {
return item.price > minPrice && item.category === activeCategory;
});
}, [list, minPrice, activeCategory]); // 依赖项变化时才重新筛选
useMemo
的场景a + b
这类轻量操作,缓存的开销可能大于重复计算的成本。const num = 1 + 2
),无需缓存。useMemo
的核心价值是 避免重复执行「昂贵且稳定」的计算,尤其是当计算结果会影响子组件渲染或存在性能瓶颈时。使用时需权衡:只有当计算成本 > 缓存成本时,优化才有意义。实际开发中,建议先通过 React DevTools 分析性能瓶颈,再针对性地使用 useMemo
。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。