1. react.memo 基础
react.memo 是一个高阶组件(hoc),用于优化函数组件的性能,通过记忆组件渲染结果来避免不必要的重新渲染。
1.1 基本用法
const memoizedcomponent = react.memo(function mycomponent(props) {
/* 渲染逻辑 */
});只有props发生变化才会重新渲染memoizedcomponent
1.2 带有比较函数的用法
const memoizedcomponent = react.memo(mycomponent, (prevprops, nextprops) => {
// 返回 true 表示不需要重新渲染
// 返回 false 表示需要重新渲染
return prevprops.id === nextprops.id;
});2. react.memo 使用场景
2.1 纯展示组件
const expensivecomponent = react.memo(function expensivecomponent({ data }) {
// 复杂的渲染逻辑
return (
<div>
{data.map(item => (
<div key={item.id}>
<h3>{item.title}</h3>
<p>{item.description}</p>
</div>
))}
</div>
);
});
// 父组件
function parentcomponent() {
const [count, setcount] = usestate(0);
const data = [/* 大量数据 */];
return (
<div>
<button onclick={() => setcount(c => c + 1)}>
count: {count}
</button>
<expensivecomponent data={data} />
</div>
);
}2.2 列表项组件
const listitem = react.memo(function listitem({ item, onitemclick }) {
console.log(`rendering item ${item.id}`);
return (
<li onclick={() => onitemclick(item.id)}>
{item.name}
</li>
);
});
function list({ items }) {
const [selectedid, setselectedid] = usestate(null);
// 使用 usecallback 来记忆回调函数
const handleitemclick = usecallback((id) => {
setselectedid(id);
}, []);
return (
<ul>
{items.map(item => (
<listitem
key={item.id}
item={item}
onitemclick={handleitemclick}
/>
))}
</ul>
);
}3. usememo 基础
usememo 是一个 hook,用于记忆计算结果,避免在每次渲染时重复进行昂贵的计算。
3.1 基本用法
const memoizedvalue = usememo(() => {
// 进行计算并返回结果
return computeexpensivevalue(a, b);
}, [a, b]); // 依赖项数组,空数组时只有初始化的时候执行,没有依赖参数项state每次变化都会引起重新执行,有依赖数组室,依赖数据发生变化才会触发重新执行4. usememo 使用场景
4.1 昂贵的计算
function dataanalytics({ data }) {
const processeddata = usememo(() => {
// 假设这是一个复杂的数据处理函数
return data.map(item => ({
...item,
processed: expensiveoperation(item)
}));
}, [data]); // 只在 data 改变时重新计算
return (
<div>
{processeddata.map(item => (
<div key={item.id}>{item.processed}</div>
))}
</div>
);
}4.2 避免子组件不必要的重新渲染
function parentcomponent({ items }) {
// 记忆对象或数组类型的 props
const memoizedvalue = usememo(() => ({
data: items,
config: {
sortby: 'name',
filterby: 'active'
}
}), [items]);
return <childcomponent options={memoizedvalue} />;
}4.3 复杂对象的派生状态
function userdashboard({ user, transactions }) {
// 计算用户统计信息
const userstats = usememo(() => {
return {
totalspent: transactions.reduce((sum, t) => sum + t.amount, 0),
averagespent: transactions.length
? transactions.reduce((sum, t) => sum + t.amount, 0) / transactions.length
: 0,
mostfrequentcategory: calculatemostfrequentcategory(transactions)
};
}, [transactions]);
return (
<div>
<userinfo user={user} />
<userstatistics stats={userstats} />
</div>
);
}5. 性能优化最佳实践
5.1 合理使用 react.memo
// ✅ 好的使用场景:纯组件,props 很少改变
const purecomponent = react.memo(function purecomponent({ data }) {
return <div>{/* 渲染逻辑 */}</div>;
});
// ❌ 不好的使用场景:props 经常变化
const frequentlychangingcomponent = react.memo(function frequentlychangingcomponent({ date }) {
return <div>{date.tolocaletimestring()}</div>;
});5.2 合理使用 usememo
// ✅ 好的使用场景:计算开销大
const expensivevalue = usememo(() => {
return someexpensiveoperation(props.data);
}, [props.data]);
// ❌ 不好的使用场景:计算开销小
const simplevalue = usememo(() => {
return props.value + 1;
}, [props.value]); // 这种情况直接计算即可5.3 配合 usecallback 使用
function searchcomponent({ onsearch }) {
const [query, setquery] = usestate('');
// 记忆回调函数
const handlesearch = usecallback(() => {
onsearch(query);
}, [query, onsearch]);
// 记忆计算结果
const searchresults = usememo(() => {
return performexpensivesearch(query);
}, [query]);
return (
<div>
<input
value={query}
onchange={e => setquery(e.target.value)}
/>
<button onclick={handlesearch}>搜索</button>
<resultslist results={searchresults} />
</div>
);
}
// 使用 react.memo 优化 resultslist
const resultslist = react.memo(function resultslist({ results }) {
return (
<ul>
{results.map(result => (
<li key={result.id}>{result.title}</li>
))}
</ul>
);
});6. 注意事项
不要过度优化
- 只在真正需要的地方使用 memo 和 usememo
- 性能测量验证优化效果
依赖项的正确使用
- 确保依赖项数组包含所有需要的值
- 避免依赖项过多导致优化失效
避免在循环中使用 usememo
// ❌ 错误示例
{items.map(item => {
const memoizedvalue = usememo(() => compute(item), [item]);
return <div>{memoizedvalue}</div>;
})}考虑内存使用
- memo 和 usememo 会占用额外的内存
- 在内存受限的环境中要谨慎使用
7. 性能优化决策流程
- 首先评估是否真的需要优化
- 使用 react devtools profiler 识别性能问题
- 选择合适的优化策略:
- 组件重新渲染优化:使用 react.memo
- 计算结果优化:使用 usememo
- 回调函数优化:使用 usecallback
- 测试优化效果
- 持续监控性能
通过合理使用 react.memo 和 usememo,我们可以显著提升 react 应用的性能。但记住,过度优化可能会适得其反,应该在实际需要时才进行优化。
到此这篇关于react 中hooks之 react.memo 和 usememo用法总结的文章就介绍到这了,更多相关react react.memo 和 usememo内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论