当前位置: 首页 > news >正文

React.memo、useMemo 和 React.PureComponent的区别

useMemo 和 React.memo 都是 React 提供的性能优化工具,但它们的作用和使用场景有显著不同。以下是两者的全面对比:

一、核心区别总结

特性useMemoReact.memo
类型React Hook高阶组件(HOC)
作用对象缓存计算结果缓存组件渲染结果
优化目标避免重复计算避免不必要的子组件重新渲染
触发条件依赖项变化时重新计算props变化时重新渲染
使用位置组件内部组件定义外层
返回值记忆化的值记忆化的组件

二、useMemo 深度解析

1、基本用法

const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);

2、主要特点

  • 缓存计算值:只有当依赖项变化时才重新计算
  • 组件内部使用:只能在函数组件或自定义Hook中使用
  • 不阻止渲染:只是优化计算过程,不影响组件是否渲染

3、典型场景

function Component({ items }) {// 只有items变化时才重新计算排序结果const sortedItems = useMemo(() => {return items.sort((a, b) => a.value - b.value);}, [items]);return <List items={sortedItems} />;
}

三、React.memo 深度解析

1、基本用法

const MemoizedComponent = React.memo(Component, arePropsEqual?);

注意:这里传递了第二个参数,它是一个自定义比较函数,用于决定是否跳过重新渲染 比如下面案例中 当判断条件为true时候 跳过渲染

2、主要特点

  • 组件记忆化:对组件进行浅比较,props不变时跳过渲染
  • 类似PureComponent:用于函数组件的shouldComponentUpdate
  • 可自定义比较:通过第二个参数控制比较逻辑

3、典型场景

const Child = React.memo(function Child({ data }) {return <div>{data.value}</div>;
});function Parent() {const [count, setCount] = useState(0);return (<><button onClick={() => setCount(c => c + 1)}>Re-render Parent</button><Child data={{ value: "Static" }} /> {/* 不会随Parent重渲染 */}</>);
}

四、关键区别

1、作用层次不同

  • useMemo:优化组件内部的计算过程
  • React.memo:优化整个组件的渲染行为

2、依赖检测方式

// useMemo 显式声明依赖
const value = useMemo(() => a + b, [a, b]);// React.memo 自动浅比较props
const MemoComp = React.memo(Comp);
// 或自定义比较
const MemoComp = React.memo(Comp, (prev, next) => prev.id === next.id); // 当上一次值和这次值的id 不一样的时候  就会触发渲染

3、性能影响对比

操作useMemo影响React.memo影响
组件重新渲染仍会执行,但可能跳过计算可能完全跳过子组件渲染
内存占用缓存计算结果缓存组件实例
适用粒度细粒度(单个值)粗粒度(整个组件)

五、联合使用示例

// 优化计算 + 优化渲染的完美组合
const ExpensiveComponent = React.memo(function({ items }) {const processedItems = useMemo(() => {return items.map(item => ({...item,fullName: `${item.firstName} ${item.lastName}`}));}, [items]);return (<ul>{processedItems.map(item => (<li key={item.id}>{item.fullName}</li>))}</ul>);
});function Parent() {const [count, setCount] = useState(0);const [items] = useState([...]);return (<><button onClick={() => setCount(c => c + 1)}>Render {count}</button><ExpensiveComponent items={items} /> {/* 父组件重渲染时,子组件不会重新渲染 */}</>);
}

六、使用建议

  • 优先考虑 React.memo:当需要防止不必要的子组件重渲染时
  • 合理使用 useMemo:对于计算量大的派生数据
  • 不要过度优化:简单的组件和计算不需要使用
  • 注意引用类型:两者都依赖浅比较,注意对象/数组的引用稳定性

七、常见误区

1、错误期待

// 以为能阻止子组件渲染(实际无效)
const Child = () => {const data = useMemo(() => ({ value: 1 }), []);return <div>{data.value}</div>;
}
// 正确做法是用React.memo包裹组件

2、错误依赖

// 依赖项不全可能导致过时闭包
const value = useMemo(() => a + b + c, [a, b]); // 缺少c

3、错误嵌套

// 不需要用useMemo缓存React.memo组件
const MemoComp = useMemo(() => React.memo(Comp), []); // 多余

八、React.memo和React.PureComponent区别

1、PureComponent 的核心作用

  • 自动实现 shouldComponentUpdate()普通 React.Component 在父组件更新或自身状态变化时总会重新渲染,而 PureComponent 会先浅比较 props 和 state,只有数据真正变化时才会触发渲染
  • 避免不必要的渲染,适用于数据变化不频繁或props/state 是简单类型(非深层嵌套对象) 的场景。

2、与 React.Component 的区别

特性React.ComponentReact.PureComponent
是否自动比较 props/state❌ 每次父组件更新或自身状态变化都会重新渲染✅ 仅当 props/state 浅比较不同时才重新渲染
适用场景需要手动优化或复杂数据变化时数据简单、变化不频繁时
性能优化需要手动实现shouldComponentUpdate()自动优化,减少不必要的渲染

3、适用场景

✅ 推荐使用 PureComponent 的情况:

  • props/state 是基本类型(string, number, boolean 等)
  • props/state 是简单对象(没有深层嵌套)
  • 组件渲染成本高(如长列表、复杂计算)

❌ 不推荐使用 PureComponent 的情况:

  • props/state 包含深层嵌套对象(浅比较无法检测内部变化)
  • 使用了可变数据(如直接修改数组或对象)
  • 需要自定义 shouldComponentUpdate 逻辑

4、代码示例

import React from 'react';// 使用 PureComponent 替代 Component
class MyComponent extends React.PureComponent {render() {console.log("只有 props/state 变化时才会重新渲染!");return <div>{this.props.value}</div>;}
}

5、注意事项

1、 浅比较(shallow compare)的局限性:PureComponent 只对比 props/state 的第一层,如果数据是深层嵌套的(如 { user: { name: ‘Alice’ } }),修改 user.name 不会触发重新渲染(因为 user 对象的引用没变
2、避免直接修改 state(应使用不可变数据)

// ❌ 错误:直接修改数组,PureComponent 无法检测变化
this.state.items.push(newItem);
this.setState({ items: this.state.items }); // 不会触发重新渲染// ✅ 正确:返回新数组
this.setState({ items: [...this.state.items, newItem] }); // 会触发重新渲染

九、PureComponent 和 React.memo 的区别

1、适用组件类型不同

却别PureComponentReact.memo
适用组件Class 组件函数组件
替代方案继承 React.PureComponent用 React.memo() 包裹函数组件
示例class MyComp extends React.PureComponentconst MyComp = React.memo(() => {…})

2、比较方式

两者都默认使用 浅比较(shallow compare),但 React.memo 更灵活:

  • PureComponent:自动比较 props 和 state,只要其中任何一个变化就重新渲染
  • React.memo:默认只比较 props(函数组件没有 state),但可以自定义比较逻辑

3、对 state 的处理

PureComponentReact.memo
是否比较 state✅ 比较 props 和 state❌ 只比较 props(函数组件依赖 useState/useReducer 管理状态
状态变化是否触发渲染✅ state 变化会触发重新渲染❌ state 变化不影响 memo(由 React Hooks 内部处理)

4、使用场景

✅ PureComponent 适用场景:

  • Class 组件,且 props/state 是简单数据类型或浅层对象
  • 不需要自定义 shouldComponentUpdate 逻辑

✅ React.memo 适用场景:

  • 函数组件,且 props 是简单数据类型或浅层对象
  • 需要自定义比较逻辑(如深层比较某些 props)

5、代码对比

(1)PureComponent(Class 组件)

import React from 'react';class MyComponent extends React.PureComponent {render() {return <div>{this.props.value}</div>;}
}

(2)React.memo(函数组件)

import React from 'react';const MyComponent = React.memo(function MyComponent(props) {return <div>{props.value}</div>;
});
http://www.dtcms.com/a/330765.html

相关文章:

  • 智慧城市SaaS平台/专项管理系统
  • 板子识别出来的所有端点号等信息
  • C++中的链式操作原理与应用(三):专注于异步操作延的C++开源库 continuable
  • 决策树 >> 随机森林
  • 智慧工地从工具叠加到全要素重构的核心引擎
  • Claude Code频繁出错怎么办?深入架构层面的故障排除指南
  • 【Linux学习|黑马笔记|Day4】IP地址、主机名、网络请求、下载、端口、进程管理、主机状态监控、环境变量、文件的上传和下载、压缩和解压
  • 【论文阅读】基于表面肌电信号的下肢多关节运动估计:一种深度卷积神经网络方法
  • [小练习]生成54张扑克牌,洗牌。
  • 解决 VSCode 运行 Python 时 ModuleNotFoundError: No module named ‘open_webui‘ 问题
  • 三角洲知识点
  • CI/CD流水线搭建流程
  • 药房发药的“时间密码”:同步时钟用药安全?
  • 抗辐照CANFD通信芯片在高安全领域国产化替代的研究
  • CMake进阶: externalproject_add用于在构建阶段下载、配置、构建和安装外部项目
  • 常见的Jmeter压测问题
  • 飞算 JavaAI 云原生实践:基于 Docker 与 K8s 的自动化部署架构解析
  • 用架构建模工具Sparx EA绘制企业转型路线图
  • C++状态模式详解:从OpenBMC源码看架构、原理与应用
  • NineData云原生智能数据管理平台新功能发布|2025年7月版
  • 云原生俱乐部-k8s知识点归纳(2)
  • 生产环境中Debezium CDC与Kafka实时流处理实战指南
  • 3ds MAX文件/贴图名称乱码?6大根源及解决方案
  • .NET 在鸿蒙系统(HarmonyOS Next)上的适配探索与实践
  • 界面设计风格解析 | ABB 3D社交媒体视觉效果设计
  • 【力扣56】合并区间
  • 一种适用于 3D 低剂量和少视角心脏单光子发射计算机断层成像(SPECT)的可泛化扩散框架|文献速递-深度学习人工智能医疗图像
  • MTK平台Wi-Fi学习--wifi channel 通过国家码进行功率限制和wifi eFEM 基本配置和wifi Tx SEM问题
  • 【深度学习】深度学习的四个核心步骤:从房价预测看机器学习本质
  • Navicat 全量增量数据库迁移