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

React 中hooks之 React.memo 和 useMemo用法总结

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 => (<ListItemkey={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 }) {// 记忆对象或数组类型的 propsconst 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><inputvalue={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. 注意事项

  1. 不要过度优化

    • 只在真正需要的地方使用 memo 和 useMemo
    • 性能测量验证优化效果
  2. 依赖项的正确使用

    • 确保依赖项数组包含所有需要的值
    • 避免依赖项过多导致优化失效
  3. 避免在循环中使用 useMemo

    // ❌ 错误示例
    {items.map(item => {const memoizedValue = useMemo(() => compute(item), [item]);return <div>{memoizedValue}</div>;
    })}
    
  4. 考虑内存使用

    • memo 和 useMemo 会占用额外的内存
    • 在内存受限的环境中要谨慎使用

7. 性能优化决策流程

  1. 首先评估是否真的需要优化
  2. 使用 React DevTools Profiler 识别性能问题
  3. 选择合适的优化策略:
    • 组件重新渲染优化:使用 React.memo
    • 计算结果优化:使用 useMemo
    • 回调函数优化:使用 useCallback
  4. 测试优化效果
  5. 持续监控性能

通过合理使用 React.memo 和 useMemo,我们可以显著提升 React 应用的性能。但记住,过度优化可能会适得其反,应该在实际需要时才进行优化。

相关文章:

React 中hooks之 React.memo 和 useMemo用法总结

1. React.memo 基础 React.memo 是一个高阶组件&#xff08;HOC&#xff09;&#xff0c;用于优化函数组件的性能&#xff0c;通过记忆组件渲染结果来避免不必要的重新渲染。 1.1 基本用法 const MemoizedComponent React.memo(function MyComponent(props) {/* 渲染逻辑 *…...

日志收集Day001

1.ElasticSearch 作用&#xff1a;日志存储和检索 2.单点部署Elasticsearch与基础配置 rpm -ivh elasticsearch-7.17.5-x86_64.rpm 查看配置文件yy /etc/elasticsearch/elasticsearch.yml&#xff08;这里yy做了别名&#xff0c;过滤掉空行和注释行&#xff09; yy /etc/el…...

机器人“大脑+小脑”范式:算力魔方赋能智能自主导航

在机器人技术的发展中&#xff0c;“大脑小脑”的架构模式逐渐成为推动机器人智能化的关键。其中&#xff0c;“大脑”作为机器人的核心决策单元&#xff0c;承担着复杂任务规划、环境感知和决策制定的重要角色&#xff0c;而“小脑”则专注于运动控制和实时调整。这种分工明确…...

python程序跑起来后,然后引用的数据文件发生了更新,python读取的数据会发生变化吗

在 Python 程序运行过程中&#xff0c;如果引用的数据文件被更新&#xff0c;程序能否读取到更新后的数据&#xff0c;取决于以下几个因素&#xff1a; 1. 是否动态读取文件 如果 Python 程序在运行过程中动态读取文件&#xff08;例如通过循环或定时机制反复打开文件读取&…...

VSCode最新离线插件拓展下载方式

之前在vscode商店有以下类似的download按钮&#xff0c;但是2025年更新之后这个按钮就不提供了&#xff0c;所以需要使用新的方式下载 ps:给自己的网站推广下~~&#xff08;国内直连GPT/Claude&#xff09; 新的下载方式1 首先打开vscode商店官网&#xff1a;vscode插件下载…...

算法题目总结-栈和队列

文章目录 1.有效的括号1.答案2.思路 2.最小栈1.答案2.思路 3.前 K 个高频元素1.答案2.思路 4.用栈实现队列1.答案2.思路 5.删除字符串中的所有相邻重复项1.答案2.思路 1.有效的括号 1.答案 package com.sunxiansheng.arithmetic.day10;import java.util.Stack;/*** Descripti…...

IO进程----进程

进程 什么是进程 进程和程序的区别 概念&#xff1a; 程序&#xff1a;编译好的可执行文件 存放在磁盘上的指令和数据的有序集合&#xff08;文件&#xff09; 程序是静态的&#xff0c;没有任何执行的概念 进程&#xff1a;一个独立的可调度的任务 执行一个程序分配资…...

【机器学习实战高阶】基于深度学习的图像分割

机器学习项目图像分割 你可能已经注意到&#xff0c;大脑如何快速高效地识别并分类眼睛感知到的事物。大脑以某种方式进行训练&#xff0c;以便能够从微观层面分析所有内容。这种能力有助于我们从一篮子橙子中分辨出一个苹果。 计算机视觉是计算机科学的一个领域&#xff0c;…...

「免填邀请码」赋能各类APP,提升转化率与用户体验

在当前移动互联网的高速发展下&#xff0c;用户获取和留存已成为各类APP成功的关键。传统的注册流程虽然能够有效识别用户来源并进行用户管理&#xff0c;但随着市场竞争的激烈&#xff0c;复杂的注册和绑定步骤往往会成为用户流失的瓶颈。免填邀请码技术&#xff0c;结合自研的…...

基于海思soc的智能产品开发(视频的后续开发)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 前面我们讨论了camera&#xff0c;也讨论了屏幕驱动&#xff0c;这些都是基础的部分。关键是&#xff0c;我们拿到了这些视频数据之后&#xff0c;…...

创建 pdf 合同模板

创建 pdf 合同模板 一、前言二、模板展示三、制作过程 一、前言 前段时间要求创建“pdf”模板&#xff0c;学会了后感觉虽然简单&#xff0c;但开始也折腾了好久&#xff0c;这里做个记录。 二、模板展示 要创建这样的模板 三、制作过程 新建一个“Word”&#xff0c;这里命…...

2024 年度学习总结

目录 1. 前言 2. csdn 对于我的意义 3. 写博客的初衷 3.1 现在的想法 4. 写博客的意义 5. 关于生活和博客创作 5.1 写博客较于纸质笔记的优势 6. 致 2025 1. 前言 不知不觉, 来到 csdn 已经快一年了, 在这一年中, 我通过 csdn 学习到了很多知识, 结识了很多的良师益友…...

CSS笔记基础篇02——浮动、标准流、定位、CSS精灵、字体图标

黑马程序员视频地址&#xff1a; 前端Web开发HTML5CSS3移动web视频教程https://www.bilibili.com/video/BV1kM4y127Li?vd_source0a2d366696f87e241adc64419bf12cab&spm_id_from333.788.videopod.episodes&p70https://www.bilibili.com/video/BV1kM4y127Li?vd_source…...

C++ 面向对象(继承)

三、继承 3.1 继承的概念 基于一个已有的类 去重新定义一个新的类&#xff0c;这种方式我们叫做继承 关于继承的称呼 一个类B 继承来自 类 A 我们一般称呼 A类&#xff1a;父类 基类 B类: 子类 派生类 B继承自A A 派生了B 示例图的语法 class vehicle // 车类 {}class …...

Top期刊算法!RIME-CNN-BiLSTM-Attention系列四模型多变量时序预测

Top期刊算法&#xff01;RIME-CNN-BiLSTM-Attention系列四模型多变量时序预测 目录 Top期刊算法&#xff01;RIME-CNN-BiLSTM-Attention系列四模型多变量时序预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 基于RIME-CNN-BiLSTM-Attention、CNN-BiLSTM-Attention、R…...

数据结构 数组

1. 常见的错误 这里我要特别纠正一个“错误”。我在面试的时候&#xff0c;常常会问数组和链表的区别&#xff0c;很多人都回答说&#xff0c;“链表适合插入、删除&#xff0c;时间复杂度O(1)&#xff1b;数组适合查找&#xff0c;查找时间复杂度为O(1)”。 实际上&#xff…...

Kivy App开发之UX控件Bubble气泡

kivy提供了一个提示气泡的小控件Bubble,使用时可以指定气泡箭头的方向以及显示的图像,还可以作为容器添加其他小控件。 常用属性如下 属性说明orientation气泡内子项的排序方式,可设置为vertical或horizontal,默认horizontalarrow_pos箭头相对于气泡的位置,可设置为left_…...

从零到一:打造属于你的AI智能体,支持本地部署

国外卷智能体&#xff0c;国内也都在搞 AI Agent&#xff0c;2025 年也将成为 Agent 的元年。构建智能体主要两种情况&#xff0c;一个是工作流模式&#xff0c;另外一种是直接开发应用&#xff0c;接下来分别给大家介绍一下两种产品和构建过程。工作流模式&#xff0c;以 Coze…...

成就与远见:2024年技术与思维的升华

个人主页&#xff1a;chian-ocean 前言: 2025年1月17日&#xff0c;2024年博客之星年度评选——创作影响力评审的入围名单公布。我很荣幸能够跻身Top 300&#xff0c;虽然与顶尖博主仍有一定差距&#xff0c;但这也为我提供了更加明确的发展方向与指引。展望崭新的2025年&…...

深搜与回溯——扫地机器人问题解析与代码实现

一、题目内容 题目描述 扫地机器人在一个 nm 的网格中从左上角&#xff08;1,1&#xff09;开始清扫。它按照以下规则移动&#xff1a; 如果当前位置的右边&#xff08;同一行&#xff0c;下一列&#xff09;没有被清扫过&#xff0c;它会向右移动。 如果右边无法移动&#xf…...

Java 语言特性(面试系列1)

一、面向对象编程 1. 封装&#xff08;Encapsulation&#xff09; 定义&#xff1a;将数据&#xff08;属性&#xff09;和操作数据的方法绑定在一起&#xff0c;通过访问控制符&#xff08;private、protected、public&#xff09;隐藏内部实现细节。示例&#xff1a; public …...

Auto-Coder使用GPT-4o完成:在用TabPFN这个模型构建一个预测未来3天涨跌的分类任务

通过akshare库&#xff0c;获取股票数据&#xff0c;并生成TabPFN这个模型 可以识别、处理的格式&#xff0c;写一个完整的预处理示例&#xff0c;并构建一个预测未来 3 天股价涨跌的分类任务 用TabPFN这个模型构建一个预测未来 3 天股价涨跌的分类任务&#xff0c;进行预测并输…...

postgresql|数据库|只读用户的创建和删除(备忘)

CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...

LINUX 69 FTP 客服管理系统 man 5 /etc/vsftpd/vsftpd.conf

FTP 客服管理系统 实现kefu123登录&#xff0c;不允许匿名访问&#xff0c;kefu只能访问/data/kefu目录&#xff0c;不能查看其他目录 创建账号密码 useradd kefu echo 123|passwd -stdin kefu [rootcode caozx26420]# echo 123|passwd --stdin kefu 更改用户 kefu 的密码…...

打手机检测算法AI智能分析网关V4守护公共/工业/医疗等多场景安全应用

一、方案背景​ 在现代生产与生活场景中&#xff0c;如工厂高危作业区、医院手术室、公共场景等&#xff0c;人员违规打手机的行为潜藏着巨大风险。传统依靠人工巡查的监管方式&#xff0c;存在效率低、覆盖面不足、判断主观性强等问题&#xff0c;难以满足对人员打手机行为精…...

智能职业发展系统:AI驱动的职业规划平台技术解析

智能职业发展系统&#xff1a;AI驱动的职业规划平台技术解析 引言&#xff1a;数字时代的职业革命 在当今瞬息万变的就业市场中&#xff0c;传统的职业规划方法已无法满足个人和企业的需求。据统计&#xff0c;全球每年有超过2亿人面临职业转型困境&#xff0c;而企业也因此遭…...

基于江科大stm32屏幕驱动,实现OLED多级菜单(动画效果),结构体链表实现(独创源码)

引言 在嵌入式系统中&#xff0c;用户界面的设计往往直接影响到用户体验。本文将以STM32微控制器和OLED显示屏为例&#xff0c;介绍如何实现一个多级菜单系统。该系统支持用户通过按键导航菜单&#xff0c;执行相应操作&#xff0c;并提供平滑的滚动动画效果。 本文设计了一个…...

Python 高级应用10:在python 大型项目中 FastAPI 和 Django 的相互配合

无论是python&#xff0c;或者java 的大型项目中&#xff0c;都会涉及到 自身平台微服务之间的相互调用&#xff0c;以及和第三发平台的 接口对接&#xff0c;那在python 中是怎么实现的呢&#xff1f; 在 Python Web 开发中&#xff0c;FastAPI 和 Django 是两个重要但定位不…...

JavaScript 标签加载

目录 JavaScript 标签加载script 标签的 async 和 defer 属性&#xff0c;分别代表什么&#xff0c;有什么区别1. 普通 script 标签2. async 属性3. defer 属性4. type"module"5. 各种加载方式的对比6. 使用建议 JavaScript 标签加载 script 标签的 async 和 defer …...

RLHF vs RLVR:对齐学习中的两种强化方式详解

在语言模型对齐&#xff08;alignment&#xff09;中&#xff0c;强化学习&#xff08;RL&#xff09;是一种重要的策略。而其中两种典型形式——RLHF&#xff08;Reinforcement Learning with Human Feedback&#xff09; 与 RLVR&#xff08;Reinforcement Learning with Ver…...