React的useEvent 和 ahooks 的 useMemorizedFn 的深度分析和对比
父组件
const TestParent: React.FC<any> = () => {const [State, setState] = useState(0);const changeFun = useCallback(() => {console.log('useCallback closure 里的 State', State);}, [State]);const changeFun_useEvent = useEvent(() => {console.log('useEvent closure 里的 State', State);});const changeFun_usememrized = useMemorizedFn(() => {console.log('useMemorizedFn closure 里的 State', State);});return (<div style={{ width: '100%', padding: '20px', backgroundColor: 'green' }}>父组件的state: {State}<button onClick={() => setState(Math.random())}>click-change state</button><TestChild changeFun={changeFun_useEvent}></TestChild><TestChild changeFun={changeFun_usememrized}></TestChild></div>);
};
子组件
const TestChild = (props: any) => {const { changeFun } = props;useEffect(() => {console.log('changeFun-》地址change了,导致了子组件刷新了。');}, [changeFun]);return (<div style={{ backgroundColor: 'pink' }}>子组件<br /><br /><button onClick={changeFun}>child click - get parent's state </button></div>);
};
React.memo(TestChild);
useEvent
已被官方废弃
useEvent 源码解析
【解释1】
1、由于每次父组件更新,都会执行到 下面的代码。这个是首要条件!

2、其次,每次执行都会传递过来一个新的handler,自然带来了新的闭包、新的数据。
3、最后,useLayoutEffect的作用是每次数据发生更新,自动的去执行里面的方法。
4、 所以 handlerRef.current 就能拿到带着最新数据的一个handler
【解释2】
useCallback 并且依赖为[],只执行一次,地址也就永远不会变了。
那么,useEvent()return出去函数的地址永不变化。
可以解释为
1、useEvent() return 出去了一个对象,为 obj = {A:{}}2、 useCallback里的箭头函数return出去的是这个 fn=handlerRef.current;相当于一个属性 A 由于handlerRef.current指向地址是不停变化的,所以A得指向地址就是不停变化的。3、因此我们真正使用 changeFun_useEvent=useEvent(xx)的时候, 拿到的是obj。永远不变的地址。changeFun_useEvent()调用的时候拿到的就是obj.A了。就是最新的带着最新数据的一个handler
function useEvent(handler: any) {const handlerRef = useRef(null);// In a real implementation, this would run before layout effects// 这行保证handlerRef一直处于,最新的闭包、拿到最新的数据。【解释1】useLayoutEffect(() => {console.log('useLayoutEffect执行了');handlerRef.current = handler;});
//这行保证返回的数据地址永远不变,但是执行的时候拿到的最新的。【解释2】return useCallback((...args: any) => {// In a real implementation, this would throw if called during renderconst fn = handlerRef.current;return fn(...args);}, []);
}
useMemorizedFn源码解析
源码地址
【解释1】
fn在这里做依赖的原因: 由于每次父组件重新执行,都会走到useMemorizedFn里并传过来一个新的箭头函数。所以fn每次地址都是新的。也就带来了新数据的闭包。fnRef.current也就是解释2里的A的地址每次都是新的,带着新的数据的闭包。
【解释2】
这里可以解释为: const obj = {A:{}} ;
memoizedFn.current = obj;
fnRef.current = A
当执行memoizedFn.current的时候也就是去访问并执行了 obj.A
function useMemorizedFn(fn: any) {const fnRef = useRef(fn);// 这行保证fn一直处于,最新的闭包、拿到最新的数据。【解释1】//这里为什么不直接 fnRef.current = fn ,可参考官网。总结就是 fnRef.current的需要放到useMemo。否则reactdev tool监听不到变化。fnRef.current = useMemo(() => {console.log('useMemo执行了'); // 父级改变就执行return fn;}, [fn]);const memoizedFn = useRef<any>();// 下面保证fn引用地址不变、且每次都能拿到最新的闭包 【解释2】if (!memoizedFn.current) {memoizedFn.current = function (this: any, ...args: any) {return fnRef.current.apply(this, args);//立即执行、改变this指向、传递参数 3个作用};}return memoizedFn.current;
}
总结
由此我们看出。其实二者的原理和出发点都是一致的,都是返回的是个固定的对象obj,该对象地址不变,但是调用的方法的时候相当于调用了obj.A,此属性的指向是会一直更新的。
只不过更新的时候 :useevent用了useLayoutCallback做更新,useMemorizedFn则使用了useMemo。
保持地址不变的时候:useevent用的是useCallback ,useMemorizedFn使用的一个 !memoizedFn.current + 新固定的function 。
此文纯属个人理解,有偏差望指正。
相关文章:
React的useEvent 和 ahooks 的 useMemorizedFn 的深度分析和对比
父组件 const TestParent: React.FC<any> () > {const [State, setState] useState(0);const changeFun useCallback(() > {console.log(useCallback closure 里的 State, State);}, [State]);const changeFun_useEvent useEvent(() > {console.log(useEv…...
基于goframe2.5.4、vue3、tdesign-vue-next开发的全栈前后端分离的管理系统
goframe-admin goframe-admin V1.0.0 平台简介 基于goframe2.5.4、vue3、tdesign-vue-next开发的全栈前后端分离的管理系统。前端采用tdesign-vue-next-starter 、vue3、pinia、tdesign-vue-next。 特征 高生产率:几分钟即可搭建一个后台管理系统认证机制&#x…...
LInux之在同一Tomcat下使用不同的端口号访问不同的项目
🎉🎉欢迎来到我的CSDN主页!🎉🎉 🏅我是君易--鑨,一个在CSDN分享笔记的博主。📚📚 🌟推荐给大家我的博客专栏《LInux实战开发》。🎯🎯 …...
梦百合上榜2023鼎革奖数字化转型先锋榜
10月26日,第六届“鼎革奖”数字化转型先锋榜单揭晓,梦百合家居凭借数字化生产的卓越成果——SAP管理平台及供应链项目,入选2023【鼎革奖】数字化转型先锋榜年度供应链转型典范,梦百合家居COO 崔慧明同步入选2023【鼎革奖】数字化转型先锋榜年度首席运营官。 据了解,「鼎革奖」数…...
沉痛悼念科研分公司
今天上班途中,遇到了上家公司的同事王强。他正准备去体检中心体检。几句寒暄之后,得知他是要入职选煤公司了。 我们所在的公司比较大,总公司下设有几十个分、子公司,我和他曾经在一家子公司——科研分公司。现在的科研分公司解散…...
Django的网站项目开发好了,该用何种方案在Centos上部署【答:Gunicorn(uWSGI)+Nginx】
问:用Django开发的网站开发好了,现在要部署上线。 系统为Centos 7.x 现在我安装好Django和相关依赖后,我用命令 python manage.py runserver 127.0.0.1:8010 启动Django 然后安装配置好Nginx,并把用的请求转发到 127.0.0.1:8010 。 请问这样的…...
基于PyTorch的中文情绪分析器设计与开发
收藏和点赞,您的关注是我创作的动力 文章目录 概要 一、相关基础理论2.1 主流深度学习框架2.2 神经网络2.2.1 神经网络基础 二、中文情感分类模型构建3.1 开发环境3.2 数据部分3.3 文本特征提取3.3.1、过滤标点符号3.3.2 中文分词、单词过滤 三 运行结果与分析五 结…...
HT5010 音频转换器工作原理
HT5010是一款低成B的立体声DA转换器,内部集成了内插滤波器、DA转换器和输出模拟滤波等电路。其可支持多种音频数字输入格式,支持24-bit字节。 该HT5010 基于一个多比特位的Δ-Σ调制器,将数字信号转化成两个声道的模拟信号并经过模拟滤波器滤…...
ubuntu18.04如何更新到22.04
将linux系统中的Ubuntu 18.04更新到22.04,按照以下步骤操作: 打开终端并更新系统,使用以下命令: sudo apt update sudo apt upgrade sudo apt dist-upgrade 确保系统是最新的,然后备份数据,以防万一。执…...
嵌入式软件开发:第二部分–七个步骤计划
使用一种工具(仅一种工具)武装自己,您可以在下一个嵌入式项目的质量和交付时间上做出巨大的改进。点击领取嵌入式物联网学习路线 该工具是:绝对承诺对开发代码的方式进行一些小而基本的更改 。 有了改变的意志,今天您…...
什么是IPA,和RPA有啥区别和联系?
∵ IPA中包含了RPA的“PA”,AI的“I” ∴IPARPAAI,等式成立! AI:或人工智能,是一种复杂的计算机技术,旨在模仿人类智能行为和决策的能力。它涵盖了多种技术和方法,包括:机器学习&am…...
内涝积水监测仪怎么样?万宾科技城市内涝积水监测的作用
在城市建设发展过程中,道路基础设施的建设永远都占据着重要一席,因为人们出行一旦受阻便会影响城市进展,也会影响经济发展。在城市之中有隧道,下穿式立交桥等容易存积水的地方,一旦出现恶劣暴雨天气,这些地…...
【java】命令行,包
文件夹情况: HelloWorld.java package com.demo; public class HelloWorld{public static void print(){System.out.println("HelloWorld!");}public static void main(String[] args){print();} } import.java import com.demo.HelloWorld; public cla…...
Generative AI 新世界 | 文生图(Text-to-Image)领域论文解读
在上期文章,我们开始探讨生成式 AI(Generative AI)的另一个进步迅速的领域:文生图(Text-to-Image)领域。概述了 CLIP、OpenCLIP、扩散模型、DALL-E-2 模型、Stable Diffusion 模型等文生图(Text…...
03.从简单的sql开始
从简单的sql开始 一、sql语句的种类二、oracle的工作原理三、oracle数据库常见基础命令 一、sql语句的种类 下面是SQL语句的分类、常用语句、使用方法: 分类语句使用方法解释数据查询SELECTSELECT column1, column2, … FROM table_name WHERE condition;用于从表…...
JS加密/解密之jsjiami在线js加密的效率问题
故事背景 经常有客户反馈,v7加密的效率比v6低,但是安全性更好。这里我给大家科普一下关于jsjiami的优化诀窍。 示例源代码 // 伪代码 while (1) {var name ‘张三’ }优化后 var _name 张三; while (1) {var name _name }优化原理 相信很多朋…...
解决【spring boot】Process finished with exit code 0的问题
文章目录 1. 复现错误2. 分析错误3. 解决问题 1. 复现错误 今天从https://start.spring.io下载配置好的spring boot项目: 启动后却报出如下错误: 即Process finished with exit code 0 2. 分析错误 Process finished with exit code 0翻译成中文进程已完…...
模电学习路径
交流通路实质 列出电路方程1,方程1对时刻t做微分 所得方程1‘ 即为 交流通路 方程1对时刻t做微分:两个不同时刻的方程1相减,并 令两时刻差为 无穷小 微分 改成 差 模电学习路径: 理论 《电路原理》清华大学 于歆杰 朱桂萍 陆文…...
【Linux】配置JDKTomcat开发环境及MySQL安装和后端项目部署
目录 一、jdk安装配置 1. 传入资源 2. 解压 3. 配置 二、Tomcat安装 1. 解压开启 2. 开放端口 三、MySQL安装 1. 解压安装 2. 登入配置 四、后端部署 1. 数据库 2. 导入.war包 3. 修改端口 4.开启访问 一、jdk安装配置 打开虚拟机 Centos 登入账号ÿ…...
Modelsim 使用教程(3)——Projects
目录 一、概述 二、设计文件及tb 2.1 设计文件 counter.v 2.2 仿真文件 tcounter.v 三、操作流程 3.1 Create a New Project(创建一个新的工程) 3.2 Add Objects to the Project(把代码加入项目) 3.3 Compile the …...
大数据学习栈记——Neo4j的安装与使用
本文介绍图数据库Neofj的安装与使用,操作系统:Ubuntu24.04,Neofj版本:2025.04.0。 Apt安装 Neofj可以进行官网安装:Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...
内存分配函数malloc kmalloc vmalloc
内存分配函数malloc kmalloc vmalloc malloc实现步骤: 1)请求大小调整:首先,malloc 需要调整用户请求的大小,以适应内部数据结构(例如,可能需要存储额外的元数据)。通常,这包括对齐调整,确保分配的内存地址满足特定硬件要求(如对齐到8字节或16字节边界)。 2)空闲…...
CentOS下的分布式内存计算Spark环境部署
一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架,相比 MapReduce 具有以下核心优势: 内存计算:数据可常驻内存,迭代计算性能提升 10-100 倍(文档段落:3-79…...
如何将联系人从 iPhone 转移到 Android
从 iPhone 换到 Android 手机时,你可能需要保留重要的数据,例如通讯录。好在,将通讯录从 iPhone 转移到 Android 手机非常简单,你可以从本文中学习 6 种可靠的方法,确保随时保持连接,不错过任何信息。 第 1…...
反射获取方法和属性
Java反射获取方法 在Java中,反射(Reflection)是一种强大的机制,允许程序在运行时访问和操作类的内部属性和方法。通过反射,可以动态地创建对象、调用方法、改变属性值,这在很多Java框架中如Spring和Hiberna…...
C# 类和继承(抽象类)
抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...
土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等
🔍 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术,可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势,还能有效评价重大生态工程…...
HDFS分布式存储 zookeeper
hadoop介绍 狭义上hadoop是指apache的一款开源软件 用java语言实现开源框架,允许使用简单的变成模型跨计算机对大型集群进行分布式处理(1.海量的数据存储 2.海量数据的计算)Hadoop核心组件 hdfs(分布式文件存储系统)&a…...
CRMEB 中 PHP 短信扩展开发:涵盖一号通、阿里云、腾讯云、创蓝
目前已有一号通短信、阿里云短信、腾讯云短信扩展 扩展入口文件 文件目录 crmeb\services\sms\Sms.php 默认驱动类型为:一号通 namespace crmeb\services\sms;use crmeb\basic\BaseManager; use crmeb\services\AccessTokenServeService; use crmeb\services\sms\…...
计算机基础知识解析:从应用到架构的全面拆解
目录 前言 1、 计算机的应用领域:无处不在的数字助手 2、 计算机的进化史:从算盘到量子计算 3、计算机的分类:不止 “台式机和笔记本” 4、计算机的组件:硬件与软件的协同 4.1 硬件:五大核心部件 4.2 软件&#…...
