react合成事件+底层原理+发展历程

news2025/1/26 15:50:59

React中的合成事件

合成事件是围绕浏览器原生事件,充当跨浏览器包装器的对象;它们将不同浏览器的行为合并为一个API,这样做是为了确保事件在不同浏览器中显示一致的属性!保证兼容性

合成事件的基本操作

基础语法:在JSX元素上,直接基于onXxx={函数} 进行事件绑定!浏览器标准事件,在React中大部分都支持


几个注意点

1.基于React内部的处理,如果我们给合成事件绑定一个普通函数,当事件行为触发,绑定的函数执行,方法中的this会是undefined

如何解决:

这是由于 JavaScript 中函数的 this 指向是动态的,会根据函数的调用方式而改变。在 React 中,给合成事件绑定的函数默认是普通函数(非箭头函数),并且函数中的 this 会默认指向 undefined。

解决这个问题有几种方法:

1. 使用箭头函数绑定事件处理函数:

handleClick = (ev) => {
  // 在箭头函数中,this 指向组件实例
   console.log(this); //实例
   console. log(ev); //SyntheticBaseEvent 合成事件对象「React内部经过特殊处理,把各个浏览器的事件对象统一化后,构建的一个事件对象」

}

render() {
  return <button onClick={this.handleClick}>Click me</button>
}

2. 在函数中使用 bind 方法将 this 绑定到组件实例:

handleClick(x,y,ev) {
  //只要方法经过bind处理了,那么最后-一个实参,就是传递的合成事件对象! !
  console.log(this, X, y, ev); //实例10 20合成事件对象

}

render() {
  return <button onClick={this.handleClick.bind(this.10,20)}>Click me</button>
}

3. 在构造函数中使用 bind 绑定方法:

constructor(props) {
  super(props);
  this.handleClick = this.handleClick.bind(this);
}

handleClick() {
  // 在这个函数中,this 指向组件实例
}

render() {
  return <button onClick={this.handleClick}>Click me</button>
}

无论使用哪种方式,都可以保证在事件触发时,方法中的 this 指向组件实例。

为什么不能用call这些!!!因为call是立即执行函数!!!所以说只能够用bind。


最直接的解决方法!!!!绑定的时候就用箭头函数

在这里插入图片描述
这里使用箭头函数绑定可以让我们的函数的this指向这个实例

合成事件的底层机制

React 处理合成事件的底层原理主要包括以下几个方面:

  1. 构建合成事件对象

React 通过在组件上面添加事件监听器的方式来处理事件,当事件触发时,会构建一个合成事件对象。合成事件对象是对原生 DOM 事件的一个封装,包含了一些特定于 React 的属性和方法,例如:

  • nativeEvent:对应原生 DOM 事件对象
  • target:事件目标
  • currentTarget:事件处理器所在的组件
  • preventDefault():阻止默认行为
  • stopPropagation():阻止事件冒泡
  1. 处理事件监听器

在调用组件的事件监听器时,React 会将原生 DOM 事件转换为一个合成事件对象,并将该合成事件对象传递给事件监听器。在事件监听器中,可以通过访问合成事件对象的属性来获取事件的相关信息。

需要注意的是,由于 React 对事件进行了委托处理,因此事件处理器并不是直接关联在真实的 DOM 元素上,而是注册在 React 的事件系统中。当事件触发时,React 会冒泡向上寻找组件树中注册了该事件处理器的组件,并将事件委派给该组件处理。经过这样的委托处理,React 保证了整个事件系统的高效运作。

  1. 更新组件

在事件处理器执行过程中,可能会修改组件的状态或者触发其他某些操作,从而需要重新渲染组件。React 通过将事件处理器的返回值与当前渲染的组件进行比较,来确定是否需要重新渲染组件。

具体来说,当事件处理器执行完后,React 会重新计算组件的状态和属性,并与之前的状态和属性进行比较。如果状态或属性发生了改变,React 就会触发更新过程,重新渲染组件并更改对应的 DOM 元素。

限制

1.当前操作的事件必须支持冒泡传播机制才可以,例如: mouseenter/mouse Leave等事件是没有冒泡传播机制的

2.如果单独做的事件绑定中,做了事件传播机制的阻止,那么事件委托中的操作也不会生效! 也就是某个组件上注册的事件处理器中使用了事件对象的 stopPropagation() 方法来阻止了事件的冒泡,那么该事件将不会继续向上冒泡到其他组件中,也就无法委托给其他组件处理。因此,其他组件上通过 React 的事件委托机制注册的事件处理器不会被触发。


几个关于处理机制的问题

顺序不对!!!
在这里插入图片描述

所以我们这里的真实过程应该是这样的

在这里插入图片描述

React的合成事件机制是通过事件委托来实现的。具体来说,当你在某个组件上注册了事件处理函数时,React会把该事件委托给祖先元素来处理。在事件冒泡阶段,React会通过委托机制把事件传递给最近的祖先组件,从而实现事件处理和状态更新的目的。

在16之前拥有的问题???
1.在React16之前,当你在某个组件上注册了事件处理函数时,React会直接为该元素注册事件处理函数,而不是将其委托给组件的祖先元素。这意味着在早期版本的React中,每个组件都有自己独立的事件监听器,当事件触发时需要相应组件分别处理,导致事件触发和处理的次数过多,从而降低了React的性能和效率。为了解决这个问题,React16之后引入了事件委托机制,将事件委托给祖先元素进行处理。同时,由于事件在传递过程中会频繁地创建和销毁事件对象,而这些对象的创建和销毁会降低React的性能,因此React16也引入了合成事件对象池,避免了重复创建和销毁大量的事件对象,提高了React的性能和效率。

2.在React16之前的版本中,React在处理事件时会直接使用原生的事件对象,而不是使用合成事件对象。这样会导致一些潜在的问题,因为不同浏览器下事件对象的行为是不一致的,使用原生事件对象会增加React的跨浏览器兼容性的问题。


在React16版本
为了提高性能,事件的处理机制从原来的委托给根元素(#root)改为委托给document元素,并且只在冒泡阶段进行事件委托。这是因为早期React版本中,事件委托机制要把事件逐级传递给每个组件进行处理,非常耗费性能。借助委托给document元素的方式,可以减少不必要的事件触发和处理,从而提高React的性能和效率。

为了避免每次事件触发都需要重新创建新的合成事件对象,React在16版本中引入了“事件对象池”缓存机制。具体来说,当每次事件触发传播到委托的元素(document/#root)上时,React会统一处理内置事件对象生成合成事件对象。然后,React从事件对象池中获取存储的合成事件对象,并把信息赋值给相关的成员。等待本次操作结束后,React会把合成事件对象中的成员信息清空,并放回事件对象池中等待下一次使用。这种机制避免了重复创建和销毁大量的合成事件对象,从而提高了React的性能和效率。


React17
17及以后版本已经去除了事件对象池和缓存机制。由于现代浏览器支持的垃圾回收机制越来越高效,重复创建和销毁合成事件对象对性能的影响已经不明显。React认为去除事件对象池可以简化底层逻辑实现,减少代码的复杂性。


React18
18中并没有对合成事件的处理机制做出重大的调整,仍然采用了委托机制和在16版本中引入的合成事件对象池。不过,React18中引入了实验性的事件优先级调度机制。该机制根据事件的类型和触发的位置计算出事件的优先级,然后把事件加入到一个优先级队列中。React根据当前应用的状态和性能情况,动态地决定哪些事件应该先被处理,哪些可以等待。这种机制可以提升React应用的响应速度和性能,具有一定的优势和潜力。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/631964.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2023蓝桥杯大学A组C++决赛游记+个人题解

Day0 发烧了一晚上没睡着&#xff0c;感觉鼻子被打火机烧烤一样难受&#xff0c;心情烦躁 早上6点起来吃了个早饭&#xff0c;思考能力完全丧失了&#xff0c;开始看此花亭奇谭 看了六集&#xff0c;准备复习数据结构考试&#xff0c;然后秒睡 一睁眼就是下午2点了 挂了个…

交通 | GAMS快速入门及其在运输问题求解的应用

推文作者​&#xff1a;AmieeXue 第一部分 GAMS编程求解运输问题 GAMS&#xff0c;全称The General Algebraic Modeling System&#xff0c;是一款通用的高级数学建模工具&#xff0c;它支持线性规划、非线性规划、混合整数规划问题、二次约束规划&#xff08;QCP&#xff09;…

《面试1v1》List

我是 javapub&#xff0c;一名 Markdown 程序员从&#x1f468;‍&#x1f4bb;&#xff0c;八股文种子选手。 《面试1v1》 连载中… 面试官&#xff1a; 小伙子,听说你对Java集合挺在行的? 候选人&#xff1a; 谢谢夸奖,我对Java集合还在学习中,只能算入门水平。特别是List这…

vue 3 第三十五章:集成 tailwind Css

文章目录 1. tailWind css介绍2. tailWind css基本使用2.1. 步骤一&#xff1a;安装Tailwind CSS2.2. 步骤二&#xff1a;创建配置文件2.3. 步骤三&#xff1a;配置PostCSS2.4. 步骤四&#xff1a;引入样式文件2.5. 步骤五&#xff1a;模板中使用tailWind css 3. 补充3.1. 语法…

【P60】JMeter Jtl 文件的 html 格式输出

文章目录 一、汇总报告&#xff08;Summary Report&#xff09;参数说明二、准备工作三、测试计划设计四、Jtl 文件的 html 格式输出 一、汇总报告&#xff08;Summary Report&#xff09;参数说明 可以查看事务或者取样器在某个时间范围内执行的汇总结果 使用场景&#xff1…

Shell脚本攻略:Linux防火墙(二)

目录 一、理论 1.SNAT 2.DNAT 3.tcpdump抓包工具 二、实验 1.SNAT实验 2.DNAT实验 3.tcpdump抓包 一、理论 1.SNAT &#xff08;1&#xff09;概念 SNAT又称源地址转换。 源地址转换是内网地址向外访问时&#xff0c;发起访问的内网ip地址转换为指定的ip地址 &#…

【软考系统规划与管理师笔记】第6篇 IT服务部署实施

这章基本也是管理概念&#xff0c;考试内容基本以教材为主 1 概述 IT服务部署实施是衔接IT服务规划设计与IT服务运营的中间阶段&#xff0c;负责对服务组 件进行客户化&#xff0c;并在充分满足客户要求的前提下&#xff0c;使用标准化的方法管理人员、资源、 技术和过程&…

【超简单的串口通信的工作原理】

上图是电脑收到来自微控制器经过串口发送的信息&#xff0c; 那么电脑是如何收到这些数据的呢&#xff1f; 任何一种通信都要包括硬件物理接口和软件通信协议。 串口通信物理接口如下图&#xff1a; 微控制器与电脑的通信仅需1根数据线将数据一位一位按顺序发送&#xff0c;称…

matlab的矩阵常用操作方法

matlab中数据的基本格式是矩阵&#xff0c;行向量、列向量和标量都是矩阵的特例。矩阵可以是二维的&#xff0c;也可以是多维的。 &#xff08;1&#xff09;查找矩阵中的元素 ①find函数 在matlab中&#xff0c;可以调用find函数在矩阵中查找满足一定条件的元素&#xff0c…

#创作纪念日# 我的创作128天纪念日

我的创作128天纪念日 机缘收获日常成就憧憬 机缘 小升初时&#xff0c;我开始接触编程&#xff0c;进入了一个全新的世界。刚开始学习编程时&#xff0c;我只是对电脑的一些操作比较感兴趣&#xff0c;但慢慢地&#xff0c;我开始对编写程序、设计算法产生了浓厚的兴趣。在实践…

创新研报 | 如何激发中国半导体企业发展潜力从而获得竞争优势,领跑新一轮增长?

近年来&#xff0c;伴随网络化、信息化、智能化飞速发展&#xff0c;半导体的应用领域不断拓展&#xff0c;在全球经济及社会发展中的重要性与日俱增。与此同时&#xff0c;越来越多的国家纷纷加码半导体&#xff0c;各个国家在半导体价值链中拥有不同的竞争优势。目前&#xf…

AI-Prompt 1.0 版简介公测!你的AI提示词网站!

提示词&#xff08;Prompt&#xff09; 是什么&#xff1f; 在 AI 大模型中&#xff0c;一个 prompt 是一个输入文本&#xff0c;用于触发模型生成输出。例如&#xff0c;当我们向一个 AI 大模型提交需求时&#xff0c;我们的需求就是一个 prompt。 在介绍产品之前&#xff0c;…

C++:二叉搜索树(非平衡化)

文章目录 一.二叉搜索树(key_value模型)二.二叉搜索树的节点删除三.二叉搜索树类对象其他接口构造函数,析构函数和赋值运算符重载节点插入接口和节点查找接口key_value模型二叉搜索树类模板总体代码 四.未经平衡化的二叉搜索树的缺陷 一.二叉搜索树(key_value模型) 树的节点定…

华为OD机试真题B卷 JavaScript 实现【数据最节约的备份方法】,附详细解题思路

一、题目描述 有若干个文件&#xff0c;使用刻录光盘的方式进行备份&#xff0c;假设每张光盘的容量是500MB。 求使用光盘最少的文件分布方式&#xff0c;所有文件的大小都是整数的MB&#xff0c;且不超过500MB&#xff0c;文件不能分隔、分卷打包。 二、输入描述 每组文件…

mysql服务器启动和关闭

Windows 系统下启动停止 MySQL 服务的方式主要有以下两种&#xff1a; 通过计算机管理方式通过CMD命令行方式 备注: 测试数据库版本为MySQL5.7。 安装mysql服务器版本5.7成功&#xff0c;且加入系统变量成功之后&#xff0c;按照以下步骤启动/停止服务器。 一、通过计算机管…

Xubuntu22.04之绘制正弦波(一百七十八)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…

测试人生 | 三十而已,何需惧怕!年薪40W+涨薪幅度超40%

关于我&#xff0c;普通二本&#xff0c;非计算机专业&#xff0c;培训出身&#xff0c;北漂&#xff0c;五年多的工作经验&#xff0c;做过外包&#xff0c;中间有过频繁的跳槽经历&#xff0c;手工点点点为主&#xff0c;最近确认了新Offer&#xff0c;远程办公&#xff0c;涨…

G - 1-n数组

第四次题组 [Cloned] - Virtual Judge (vjudge.net) 【题目描述】 给你一个数组一个a[n]组成n正整数。您可以对其执行操作。 在一个操作中&#xff0c;您可以替换数组的任何元素一个我​跟⌊/2​​⌋ 看看您是否可以多次应用该操作&#xff08;可能操作为0&#xff09; 来制…

Apache Commons CSV 基本使用

Apache Commons CSV 基本使用 文章目录 Apache Commons CSV 基本使用一、概述1、简介2、主要特点3、官方资料 二、基本使用1、引入依赖2、读取 .csv 文件文件内容读取文件 3、写入文件写入文件写入结果 一、概述 1、简介 Apache Commons CSV是Apache软件基金会的一个开源项目…

Android——认识Android (Android发展简介)(一)

如果想要学习好Android开发&#xff0c;首先需要能够熟练应用以下的几个知识&#xff1a; JavaSE : 理解面向对象&#xff0c;掌握网络通信&#xff0c;掌握集合&#xff0c;掌握IO操作&#xff0c;要懂得图形化界面swing。 JavaEE&#xff1a;也需要一定的了解&#xff0c;以…