React 第十七节 useMemo用法详解
概述
useMemo 是React 中的一个HOOK,用于根据依赖在每次渲染时候缓存计算结果;
大白话就是,只有依赖项发生变化时候,才会重新渲染为新计算的值,否则就还是取原来的值,有点类似 vue 中的 computed 计算属性,注意与 useEffect 区分;
写法
const value = useMemo(fnc, [a,b])
第一个参数:fnc 是一个函数,用于根据 依赖项 a、b变化时候触发计算得出新值,必须是一个没有任何参数的纯函数,可以返回任意类型;若 a、b没有变化,则React 返回与上次相同的值;若 a、b 发生改变,则会返回新的值;
第二个参数:[a、b] 是一个数组,函数 fnc中计算所依赖的值,这个数组中若不传入具体变量,而是传入 空数组[],那么会在组件每次更新时候重新渲染;
这种缓存值的方式叫做 记忆化 (memoization), 这也是这个Hook 称为 useMemo 的由来;
使用场景
1、当我们在 useMemo 中的代码运行很慢,通过使用 useMemo 运行效率得到显著提升;
2、将计算结果作为 props 传递给包裹在 memo 中的组件。当计算结果没有改变时,你会想跳过重新渲染。记忆化让组件仅在依赖项不同时才重新渲染。
3、你传递的值稍后用作某些 Hook 的依赖项。例如,也许另一个 useMemo 计算值依赖它,或者 useEffect 依赖这个值。
例如:
将计算结果作为 props 传给子组件
// 父组件
import React, {useMemo, useState} from 'react'
import ChildA from './childA'
export default function MyMemo() {const [firstName, setFirstName] = useState('Andy')const [lastName, setLastName] = useState('Li')const [count, setCount] = useState(0)const fullName = useMemo(() => {console.log('==useMemo==')return firstName +'' + lastName}, [firstName, lastName]) // 第二个参数是数组,表示fullName 依赖 firstName 和 lastName 的值,只有 firstName 和 lastName 值发生变化,fullName 才重新计算const handleChangeName = (e, type) => {console.log('==handleChangeName==', e)// [`set${type}`](e.target.value)// if (type === 'FirstName') {// setFirstName(e.target.value)// } else {// setLastName(e.target.value)// }}const handleChangeFirstName = () => {console.log('==更新第一个名称=')setCount(count+1)setFirstName(11)}return (<div><input type="text" value={firstName} onChange={(e) => handleChangeName(e, 'FirstName')} /><p>点击了{count}次</p><button onClick={handleChangeFirstName}>firstName</button><br/><input type="text" value={lastName} onChange={(e) => handleChangeName(e, 'LastName')} /><hr /><ChildA fullName={fullName}></ChildA></div>)
}
// 子组件
import React, {memo, useState} from 'react'
const ChildA = memo(({fullName}) =>{console.log('=render=ChildA==fullName----', fullName)return (<div><p>全称:{fullName}</p></div>)
})
export default ChildA

通过 log日志,我们可以发现,共计点击了 firstName 按钮 18次;只有在初始化和第一次点击时候才会渲染 子组件;
因为第一次点击将 firstName 更新为 11;之后的点击传入相同的值 11,导致 useMemo 返回的 fullName 是相同的,故不再进行渲染
而当我们使用 useEffect 时候,会每次都更新子组件
注意:
1、useMemo 只能作为组件代码性能优化使用,如果在不使用 useMemo时,代码无法正常运行,那么我们需要先排查问题,之后再使用 useMemo;
2、避免不必要的更新 state 的 Effect;React 中很多的性能是由于其自身的更新链导致的,所以我们要避免重复的更新同一个组件;
3、尽可能的减少依赖项,避免过多的依赖导致代码难以理解,难以追踪问题;我们可以将依赖项 设置成 state;
4、我们应该减少状态的提升,多使用state,而不是滥用useMemo来处理性能;
相关文章:
React 第十七节 useMemo用法详解
概述 useMemo 是React 中的一个HOOK,用于根据依赖在每次渲染时候缓存计算结果; 大白话就是,只有依赖项发生变化时候,才会重新渲染为新计算的值,否则就还是取原来的值,有点类似 vue 中的 computed 计算属性…...
鸿蒙项目云捐助第十五讲云数据库的初步使用
鸿蒙项目云捐助第十五讲云数据库的初步使用 在华为云技术使用中,前面使用了云函数,接下来看一下华为云技术中的另外一个技术云数据库的使用。 一、云数据库的创建 这里使用华为云数据库也需要登录到AppGallery Connect平台中,点击进入到之…...
如何构建一个可信的联邦RAG系统。
今天给大家分享一篇论文。 题目是:C-RAG:如何构建一个可信的联邦检索RAG系统。 论文链接:https://arxiv.org/abs/2412.13163 论文概述 尽管大型语言模型 (LLM) 在各种应用中展现出令人印象深刻的能力,但它们仍然存在可信度问题ÿ…...
【深度学习之三】FPN与PAN网络详解
FPN与PAN:深度学习中的特征金字塔网络与路径聚合网络 在深度学习的领域里,特征金字塔网络(Feature Pyramid Networks,简称FPN) 和 路径聚合网络(Path Aggregation Network,简称PAN)…...
Qt学习笔记第71到80讲
第71讲 事件过滤器的方式实现滚轮按键放大 事件体系(事件派发 -> 事件过滤->事件分发->事件处理)中,程序员主要操作的是事件分发与事件处理。我们之前已经通过继承QTextEdit来重写事件实现Ctrl加滚轮的检测,还有一种处理…...
以管理员身份运行
同时按下Ctrl Shift Esc键打开任务管理器,在任务管理器的左上角,点击“文件”菜单,在下拉菜单中选择“新建任务” 在弹出的对话框中,输入您想要运行的程序的名称。如果您不确定程序的确切名称,可以点击“浏览”来找到…...
用 Python 实现井字棋游戏
一、引言 井字棋(Tic-Tac-Toe)是一款经典的两人棋类游戏。在这个游戏中,玩家轮流在 3x3 的棋盘上放置自己的标记,通常是 “X” 和 “O”,第一个在棋盘上连成一线(横、竖或斜)的玩家即为获胜者。…...
06 实现自定义AXI DMA驱动
为什么要实现自定义AXI DMA驱动 ZYNQ 的 AXI DMA 在 Direct Register DMA (即 Simple DMA)模式下可以通过 AXIS 总线的 tlast 提前结束传输,同时还可以在 BUFFLEN 寄存器中读取到实际传输的字节数,但是通过 Linux 的 DMA 驱动框架…...
SpringBoot集成ENC对配置文件进行加密
在线MD5生成工具 配置文件加密,集成ENC 引入POM依赖 <!-- ENC配置文件加密 --><dependency><groupId>com.github.ulisesbocchio</groupId><artifactId>jasypt-spring-boot-starter</artifactId><version>2.1.2</ver…...
初学stm32 ——— 串口通信
目录 STM32的串口通信接口 UART异步通信方式特点: 串口通信过程 STM32串口异步通信需要定义的参数: USART框图: 常用的串口相关寄存器 串口操作相关库函数 编辑 串口配置的一般步骤 STM32的串口通信接口 UART:通用异步收发器USART&am…...
qwt 多Y轴 项目效果
项目场景: 在做一个半导体上位机软件项目实践中,需要做一个曲线展示和分析界面,上位机主题是用qt框架来开发,考虑到目前qt框架的两种图标库,一个是qcustomplot 一个是 qwt。之所以采用qwt ,根本原因是因为…...
Java中通过ArrayList扩展数组
在Java中,ArrayList 是一个动态数组实现,能够根据需要自动调整其大小。与传统的数组不同,ArrayList 不需要预先指定大小,并且提供了许多方便的方法来操作集合中的元素。下面将详细介绍如何使用 ArrayList 进行数组的扩展ÿ…...
Java:链接redis报错:NoSuchElementException: Unable to validate object
目录 前言报错信息排查1、确认redis密码设置是否有效2、确认程序配置文件,是否配置了正确的redis登录密码3、检测是否是redis持久化的问题4、确认程序读取到的redis密码没有乱码 原因解决 前言 一个已经上线的项目,生产环境的redis居然没有设置密码&…...
datasets库之load_dataset
目录 问题解决方案 问题 使用peft用lora微调blip2时用到了一个足球数据集,如下: 原始代码如下 dataset load_dataset("ybelkada/football-dataset", split"train")然而这需要梯子才能下载,服务器较难用VPN所以使用au…...
React Router常见面试题目
1. React Router 支持哪几种模式? React Router 支持以下两种主要模式: BrowserRouter (基于 HTML5 History API 的模式) 原理: 利用 history.pushState 和 history.replaceState 操作浏览器历史栈,无需重新加载页面。URL 看起来像传统 URL…...
sequelize-cli 封装登录接口
node ORM (sequelize)使用、查询、验证及express 基础框架的搭建及实例的使用 一、思路 第一步:肯定是用户要向接口传递邮箱、账号和密码了。 第二步:接口这边,先要验证。因为这里不是往数据库里存储数据,…...
使用 Elasticsearch 查询和数据同步的实现方法
在开发过程中,将数据从数据库同步到 Elasticsearch (ES) 是常见的需求之一。本文将重点介绍如何通过 Python 脚本将数据库中的数据插入或更新到 Elasticsearch,并基于多字段的唯一性来判断是否执行插入或更新操作。此外,我们还将深入探讨如何…...
QTday1作业设置简易登录界面
代码 #include "mywidget.h"MyWidget::MyWidget(QWidget *parent): QWidget(parent) {//创建一个标签QLabel *lab1 new QLabel(this);//重新设置大小lab1->resize(1925,1080);//用动图类QMovie实例化一个动图QMovie *mv new QMovie("C:\\Users\\MR\\Deskto…...
RC低通滤波器和LR低通滤波器,LC低通滤波器该怎么选择
这是RC低通滤波器利用电容两端的电压不能突变可以滤除高频噪声 这是LR低通滤波器利用流过电感的电流不能突变也可以滤除高频噪声 那么问题来了两个低通滤波器,该怎么选择呢还是随便选一个就好? RC电路:因为电流电阻会发热耗能,所…...
芯旺微KF32A156芯片ADC配置
使用芯旺微KF32A156的芯片做预研项目,使用了ADC0外设,根据芯片规格书中的描述进行了配置: /*** brief: Configure ADC.** param[in] none.* param[in] none.* param[out] None* retval: None*/ static void adc_peripheral_init(void) …...
避开这些坑!在PX4 1.14.0上添加自定义串口传感器的完整避坑指南
PX4 1.14.0自定义串口传感器开发实战:从设备注册到数据解析全链路避坑指南 当你在PX4飞控上尝试接入一款新型激光雷达时,是否遇到过这样的场景:按照官方文档一步步操作,编译通过后却发现传感器始终无法输出有效数据?本…...
HiOmics平台:零代码实现ChIP-Seq数据可视化与深度解析
1. 为什么科研人员需要零代码ChIP-Seq分析工具 做表观遗传学研究的朋友们应该都深有体会,ChIP-Seq数据分析就像一场马拉松——从原始数据清洗、序列比对、peak calling到功能注释,每个环节都需要不同的工具和脚本。我刚开始接触这个领域时,光…...
【C语言】memmove()函数实战:如何安全高效地处理内存重叠拷贝
1. 为什么需要memmove()函数? 在C语言中处理内存拷贝时,我们经常会遇到一个棘手的问题:当源内存块和目标内存块存在重叠区域时,使用memcpy()函数可能会导致数据被意外覆盖。想象一下你在整理书架,想把第三层到第五层的…...
Python 3.14 JIT编译延迟高达83ms?这不是Bug,是设计——揭秘AST→LLVM IR→Native Code三级缓存失效链
第一章:Python 3.14 JIT编译器性能调优架构设计图Python 3.14 引入的实验性 JIT 编译器(代号 “Triton”)采用分层编译策略,将热点函数动态划分为解释执行、字节码优化、LLVM IR 生成与本地机器码缓存四个协同层级。其核心设计目标…...
2026技术展望】Python与AI的深度融合:从“能用”到“好用”的质变之年
🔥个人主页:北极的代码(欢迎来访) 🎬作者简介:java后端学习者 ❄️个人专栏:苍穹外卖日记,SSM框架深入,JavaWeb ✨命运的结局尽可永在,不屈的挑战却不可须臾或…...
002MCP
MCP...
Wi-Fi 6高密度网络优化:实战漫游与性能提升
Wi-Fi 6高密度网络优化:实战漫游与性能提升在诸如大型企业园区、高流量高校、人流密集的会展中心等高密度用户环境中,传统Wi-Fi网络面临着严峻的无线接入挑战。Wi-Fi 6 (802.11ax) 标准以更高的频谱效率、更低的延迟和卓越的设备并发能力,为解…...
【NX二次开发】cam对象类型
//此函数的功能是打印当前坐标系试图的所有坐标系名称 static void geom_list_name(tag_t group_tag) { //ask_member_list int count=0; tag_t *list=NULL; //ask_name char name[UF_OBJ_NAME_LEN+1]; //ask_type_and_subtype int type=0; in…...
阿里千问Qwen3.5-Omni:全模态大模型的新王者
Qwen3.5-Omni:全模态能力的新巅峰3月30日,阿里发布的千问新一代全模态大模型Qwen3.5-Omni,在音视频理解、识别、交互等215项任务中取得SOTA(性能最佳),超越Gemini-3.1 Pro,成为全球最强的全模态…...
实体店有没有必要做门店小程序?
在当前消费行为不断向线上延伸的背景下,实体店是否需要搭建门店小程序,已经成为很多经营者在数字化转型过程中必须面对的问题。实体店是否有必要做门店小程序,取决于其是否需要提升获客能力与用户复购效率。一、为什么会出现这个问题在实际经…...
