如何使用 useMemo 和 memo 优化 React 应用性能?
使用 useMemo
和 memo
优化 React 应用性能
在构建复杂的 React 应用时,性能优化是确保应用流畅运行的关键。React 提供了多种工具来帮助开发者优化组件的渲染和计算逻辑,其中 useMemo
和 memo
是两个非常有用的 Hook。本文将详细介绍这两个工具的使用方法及其应用场景。
1. useMemo
的介绍与使用
1.1 什么是 useMemo
?
useMemo
是一个 React Hook,用于记忆(缓存)某些计算结果,以避免不必要的重复计算。它接收两个参数:一个返回值的计算函数和一个依赖项数组。只有当依赖项发生变化时,useMemo
才会重新计算并返回新的值;否则,它将返回之前缓存的结果。
1.2 useMemo
的语法
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
computeExpensiveValue(a, b)
是一个计算昂贵值的函数。[a, b]
是依赖项数组,只有当这些依赖项发生变化时,useMemo
才会重新执行计算。
1.3 示例:优化总价计算
在你的 Test2.tsx
组件中,total
函数用于计算商品的总价。每次组件重新渲染时,total
都会重新计算。为了优化这一点,我们可以使用 useMemo
来缓存计算结果:
import React, { useState, useMemo } from 'react';export default function Test2() {const [search, setSearch] = useState('');const [list, setList] = useState([{ id: 1, name: '苹果', price: 10, count: 1 },{ id: 2, name: '小米', price: 20, count: 1 },{ id: 3, name: '华为', price: 30, count: 1 },]);const handleAdd = (id: number) => {setList(list.map(item => item.id === id ? { ...item, count: item.count + 1 } : item));};const handleSub = (id: number) => {setList(list.map(item => item.count > 1 && item.id === id ? { ...item, count: item.count - 1 } : item));};// 使用 useMemo 缓存总价计算结果const total = useMemo(() => {return list.reduce((pre, cur) => pre + cur.price * cur.count, 0);}, [list]);return (<div><h1>父组件</h1><input type="text" value={search} onChange={(e) => setSearch(e.target.value)} /><table border={1} cellPadding={5} cellSpacing={0}><thead><tr><th>商品名称</th><th>商品价格</th><th>商品数量</th></tr></thead><tbody>{list.map(item => (<tr key={item.id}><td>{item.name}</td><td>{item.price * item.count}</td><td><button onClick={() => handleAdd(item.id)}>+</button><span>{item.count}</span><button onClick={() => handleSub(item.id)}>-</button></td></tr>))}</tbody><tfoot><tr><th scope="row" colSpan={1}>总价</th><td>{total}</td></tr></tfoot></table></div>);
}
在这个例子中,useMemo
确保只有当 list
发生变化时才会重新计算 total
,从而减少了不必要的计算开销。
2. memo
的介绍与使用
2.1 什么是 memo
?
memo
是 React 提供的一个高阶组件(HOC),用于防止子组件不必要的重新渲染。它通过比较当前和上次渲染的 props 来决定是否需要重新渲染组件。如果 props 没有变化,则跳过渲染,直接复用之前的渲染结果。
2.2 memo
的语法
const MemoizedComponent = React.memo(MyComponent);
MyComponent
是你想要优化的组件。React.memo
返回一个新的组件,该组件会在 props 没有变化时不重新渲染。
2.3 示例:优化子组件渲染
假设我们有一个子组件 ProductItem
,它负责显示单个商品的信息。我们可以使用 memo
来优化这个组件,避免不必要的重新渲染:
import React from 'react';
import { memo } from 'react';interface ProductItemProps {product: { id: number; name: string; price: number; count: number };onAdd: () => void;onSub: () => void;
}const ProductItem: React.FC<ProductItemProps> = ({ product, onAdd, onSub }) => {console.log('ProductItem rendered');return (<tr key={product.id}><td>{product.name}</td><td>{product.price * product.count}</td><td><button onClick={onAdd}>+</button><span>{product.count}</span><button onClick={onSub}>-</button></td></tr>);
};// 使用 memo 包装 ProductItem 组件
const MemoizedProductItem = memo(ProductItem);export default MemoizedProductItem;
在这个例子中,MemoizedProductItem
只会在其 props
发生变化时重新渲染,否则会复用之前的渲染结果,从而提高性能。
3. useMemo
和 memo
的区别
-
作用范围:
useMemo
用于优化组件内部的计算逻辑,减少不必要的计算。memo
用于优化组件的渲染行为,减少不必要的重新渲染。
-
使用场景:
- 当你在组件内部有复杂的计算逻辑时,可以使用
useMemo
来缓存计算结果。 - 当你有一个子组件频繁重新渲染但实际内容没有变化时,可以使用
memo
来优化渲染性能。
- 当你在组件内部有复杂的计算逻辑时,可以使用
4. 总结
useMemo
和 memo
是 React 中非常强大的工具,能够显著提升应用的性能。合理使用它们可以帮助你避免不必要的计算和渲染,从而让应用更加高效和流畅。希望本文能帮助你更好地理解和使用这两个工具,为你的 React 应用带来更好的用户体验。
相关文章:
如何使用 useMemo 和 memo 优化 React 应用性能?
使用 useMemo 和 memo 优化 React 应用性能 在构建复杂的 React 应用时,性能优化是确保应用流畅运行的关键。React 提供了多种工具来帮助开发者优化组件的渲染和计算逻辑,其中 useMemo 和 memo 是两个非常有用的 Hook。本文将详细介绍这两个工具的使用方…...

数据结构(链表 哈希表)
在Python中,链表和哈希表都是常见的数据结构,可以用来存储和处理数据。 链表是一种线性数据结构,由一系列节点组成,每个节点包含一个数据元素和一个指向下一个节点的指针。链表可以用来实现栈、队列以及其他数据结构。Python中可…...

人工智能之深度学习_[4]-神经网络入门
神经网络基础 1 神经网络 深度学习神经网络就是大脑仿生,数据从输入到输出经过一层一层的神经元产生预测值的过程就是前向传播(也叫正向传播)。 前向传播涉及到人工神经元是如何工作的(也就是神经元的初始化、激活函数…...

STM32之CubeMX图形化工具开发介绍(十七)
STM32F407 系列文章 - STM32CubeMX(十七) 目录 前言 一、CubeMX 二、下载安装 1.下载 2.安装 3.图解步骤 三、用户界面 1.项目配置 2.项目生成 3.项目文件解释 4.新建工程 5.查看原工程 四、FAQ 总结 前言 STMCube源自意法半导体…...
css3过渡总结
一、过渡的定义与作用 CSS3 过渡(Transitions)允许 CSS 属性在一定的时间区间内平滑地过渡,从一个值转变为另一个值。它能够让网页元素的状态变化更加自然、流畅,给用户带来更好的视觉体验。例如,当一个元素从隐藏状态…...

latin1_swedish_ci(latin1 不支持存储中文、日文、韩文等多字节字符)
文章目录 1、SHOW TABLE STATUS WHERE Name batch_version;2、latin1_swedish_ci使用场景注意事项修改字符集和排序规则修改表的字符集和排序规则修改列的字符集和排序规则修改数据库的默认字符集和排序规则 3、ALTER TABLE batch_version CONVERT TO CHARACTER SET utf8mb4 C…...

C语言编程笔记:文件处理的艺术
大家好,这里是小编的博客频道 小编的博客:就爱学编程 很高兴在CSDN这个大家庭与大家相识,希望能在这里与大家共同进步,共同收获更好的自己!!! 本文目录 引言正文一、为什么要用文件二、文件的分…...
[创业之路-255]:《华为数字化转型之道》-1-主要章节、核心内容、核心思想
目录 前言:数字化转型对于企业而言,是一种全方位的变革 一、主要章节 1、认知篇(第1~2章)- Why 2、方法篇(第3~5章)- How 3、实践篇(第6~10章)- 实践 4、平台篇(第…...

《汽车维修技师》是什么级别的期刊?是正规期刊吗?能评职称吗?
问题解答: 问:《汽车维修技师》是不是核心期刊? 答:不是,是知网收录的正规学术期刊。 问:《汽车维修技师》级别? 答:省级。主管单位:北方联合出版传媒(…...

2024 京东零售技术年度总结
每一次回望,都为了更好地前行。 2024 年,京东零售技术在全面助力业务发展的同时,在大模型应用、智能供应链、端技术、XR 体验等多个方向深入探索。京东 APP 完成阶段性重要改版,打造“又好又便宜”的优质体验;国补专区…...

PyTorch使用教程(8)-一文了解torchvision
一、什么是torchvision torchvision提供了丰富的功能,主要包括数据集、模型、转换工具和实用方法四大模块。数据集模块内置了多种广泛使用的图像和视频数据集,如ImageNet、CIFAR-10、MNIST等,方便开发者进行训练和评估。模型模块封装了大量经…...
如何在不暴露MinIO地址的情况下,用Spring Boot与KKFileView实现文件预览
在现代Web应用中,文件预览是一项常见且重要的功能。它允许用户在不上传或下载文件的情况下,直接在浏览器中查看文件内容。然而,直接将文件存储服务(如MinIO)暴露给前端可能会带来安全风险。本文将介绍如何在不暴露MinI…...

ICMP协议和ICMP重定向攻击
✍作者:柒烨带你飞 💪格言:生活的情况越艰难,我越感到自己更坚强;我这个人走得很慢,但我从不后退。 📜系列专栏:网络安全从菜鸟到飞鸟的逆袭 目录 一,ICMP基本概念二&…...

leetcode203-移除链表元素
leetcode203 什么是链表 之前不懂链表的数据结构,一看到链表的题目就看不明白 链表是通过next指针来将每个节点连接起来的,题目中给的链表是单向链表,有两个值,一个val表示值,一个next:表示连接的下一个…...
Rust 中构建 RESTful API
在 Rust 中构建 RESTful API,你可以选择几个不同的框架。每个框架有不同的特点、优缺点和适用场景,下面我将介绍几个常用的 Rust Web 框架,并分析它们的优缺点。 Actix Web 简介: Actix Web 是一个非常高性能的 Web 框架…...

Sqlmap入门
原理 在owasp发布的top10 漏洞里面,注入漏洞一直是危害排名第一,其中数据库注入漏洞是危害的。 当攻击者发送的sql语句被sql解释器执行,通过执行这些恶意语句欺骗数据库执行,导致数据库信息泄漏 分类 按注入类型 常见的sql注入…...

迈向 “全能管家” 之路:机器人距离终极蜕变还需几步?
【图片来源于网络,侵删】 这是2024年初Figure公司展示的人形机器人Figure 01,他可以通过观看人类的示范视频,在10小时内经过训练学会煮咖啡,并且这个过程是完全自主没有人为干涉的! 【图片来源于网络,侵删】…...

移动端 REM 适配
移动端 REM 适配 Vant 中的样式默认使用 px 作为单位,如果需要使用 rem 单位,推荐使用以下两个工具: postcss-pxtorem 是一款 postcss 插件,用于将单位转化为 remlib-flexible 用于设置 rem 基准值 下面我们分别将这两个工具配…...
逐笔成交逐笔委托Level2高频数据下载和分析:20241230
逐笔委托逐笔成交下载 链接: https://pan.baidu.com/s/11Tdq06bbYX4ID9dEaiv_lQ?pwdcge6 提取码: cge6 Level2逐笔成交逐笔委托数据分享下载 利用Level2的逐笔交易和委托数据,这种以毫秒为单位的详细信息能揭露众多关键信息,如庄家意图、伪装行为&…...

C#实现字符串反转的4种方法
见过不少人、经过不少事、也吃过不少苦,感悟世事无常、人心多变,靠着回忆将往事串珠成链,聊聊感情、谈谈发展,我慢慢写、你一点一点看...... 1、string.Reverse 方法 string content "Hello World";string reverseStri…...

地震勘探——干扰波识别、井中地震时距曲线特点
目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波:可以用来解决所提出的地质任务的波;干扰波:所有妨碍辨认、追踪有效波的其他波。 地震勘探中,有效波和干扰波是相对的。例如,在反射波…...
R语言AI模型部署方案:精准离线运行详解
R语言AI模型部署方案:精准离线运行详解 一、项目概述 本文将构建一个完整的R语言AI部署解决方案,实现鸢尾花分类模型的训练、保存、离线部署和预测功能。核心特点: 100%离线运行能力自包含环境依赖生产级错误处理跨平台兼容性模型版本管理# 文件结构说明 Iris_AI_Deployme…...
【Linux】C语言执行shell指令
在C语言中执行Shell指令 在C语言中,有几种方法可以执行Shell指令: 1. 使用system()函数 这是最简单的方法,包含在stdlib.h头文件中: #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...

IT供电系统绝缘监测及故障定位解决方案
随着新能源的快速发展,光伏电站、储能系统及充电设备已广泛应用于现代能源网络。在光伏领域,IT供电系统凭借其持续供电性好、安全性高等优势成为光伏首选,但在长期运行中,例如老化、潮湿、隐裂、机械损伤等问题会影响光伏板绝缘层…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用
1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...
JS手写代码篇----使用Promise封装AJAX请求
15、使用Promise封装AJAX请求 promise就有reject和resolve了,就不必写成功和失败的回调函数了 const BASEURL ./手写ajax/test.jsonfunction promiseAjax() {return new Promise((resolve, reject) > {const xhr new XMLHttpRequest();xhr.open("get&quo…...
腾讯云V3签名
想要接入腾讯云的Api,必然先按其文档计算出所要求的签名。 之前也调用过腾讯云的接口,但总是卡在签名这一步,最后放弃选择SDK,这次终于自己代码实现。 可能腾讯云翻新了接口文档,现在阅读起来,清晰了很多&…...

【JVM】Java虚拟机(二)——垃圾回收
目录 一、如何判断对象可以回收 (一)引用计数法 (二)可达性分析算法 二、垃圾回收算法 (一)标记清除 (二)标记整理 (三)复制 (四ÿ…...

打手机检测算法AI智能分析网关V4守护公共/工业/医疗等多场景安全应用
一、方案背景 在现代生产与生活场景中,如工厂高危作业区、医院手术室、公共场景等,人员违规打手机的行为潜藏着巨大风险。传统依靠人工巡查的监管方式,存在效率低、覆盖面不足、判断主观性强等问题,难以满足对人员打手机行为精…...

在 Spring Boot 中使用 JSP
jsp? 好多年没用了。重新整一下 还费了点时间,记录一下。 项目结构: pom: <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://ww…...