React系列之合成事件与事件处理机制

文章目录

  • React事件处理机制
    • 原生事件的事件机制
      • 事件代理(事件委托)
    • 合成事件
      • 使用合成事件目的
      • 合成事件原生事件区别
      • 事件池
    • 原生事件和React事件的执行顺序
      • e.stopPropagation()
    • React17事件机制的修改

React事件处理机制

react 事件机制基本理解:react 基于浏览器的事件机制,自身实现了一套自己的事件机制,包括事件注册、事件的合成、事件冒泡、事件派发等。
react 的所有事件并没有绑定到具体的dom节点上而是绑定在了 document 上,然后由统一的事件处理程序来处理,同时也是基于浏览器的事件机制(冒泡),所有节点的事件都会在 document 上触发。

React 的事件处理机制可以分为两个阶段:

  • 初始化渲染时在 root 节点上注册原生事件;
  • 原生事件触发时模拟、目标和冒泡阶段派发合成事件。
    通过这种机制,冒泡的原生事件类型最多在 root 节点上注册一次,节省内存开销。且 React 为不同类型的事件定义了不同的处理优先级,从而让用户代码及时响应高优先级的用户交互,提升用户体验。

合成事件是 React 模拟原生 DOM 事件所有能力的一个事件对象,它可以兼容所有浏览器,也拥有和浏览器原生事件相同的接口。

原生事件的事件机制

在这里插入图片描述
事件流向分为三个阶段:捕获阶段、目标阶段、冒泡阶段。
捕获阶段是指事件响应从最外层的Window开始逐层向内层推进,直到具体的目标元素。
目标阶段是触发事件的目标元素。
冒泡阶段与捕获阶段相反,事件的响应是从最底层开始一层层向外传递到最外层的Window。

我们可以通过element.addEventListener()设置一个元素的事件模型为冒泡事件还是捕获事件。
element.addEventListener(type, listener, useCapture)
type:监听的事件类型(例’click’)
listener:事件的回调函数
useCapture:默认值为false,表示元素事件模型为事件冒泡,设为true时为事件捕获。

在这里插入图片描述

事件代理(事件委托)

事件代理(也称为事件委托)是一种利用DOM事件机制,通过将事件处理程序添加到父元素而不是每个子元素上来提高性能的技术。当子元素上的事件触发时,事件会冒泡/捕获到父元素,然后由父元素上的事件处理程序进行处理。
例对于列表元素,我们希望将用户点击了哪个item打印出来,通常我们可以给每个item注册点击事件监听器,但通过事件代理,可以将多个事件监听器减少为一个,这样可以减少重复工作,也可以减少内存。还可以使新增元素动态绑定事件。

var items = document.getElementById('item-list');
//事件捕获实现事件代理
items.addEventListener('click', (e) => {console.log('捕获:click ',e.target.innerHTML)}, true);
//事件冒泡实现事件代理
items.addEventListener('click', (e) => {console.log('冒泡:click ',e.target.innerHTML)}, false);

事件代理既可以通过事件冒泡来实现,也可以通过事件捕获来实现。

合成事件

React 合成事件(SyntheticEvent)是 React 模拟原生 DOM 事件所有能力的一个事件对象,即浏览器原生事件的跨浏览器包装器。它根据 W3C 规范来定义合成事件,兼容所有浏览器,拥有与浏览器原生事件相同的接口。

即在react中,我们绑定的事件onClick等,并不是原生事件,而是由原生事件合成的React事件,比如 click 事件合成为 onClick 事件。比如 blur, change, input, keydown, keyup, 合成为 onChange。可以通过 e.nativeEvent 属性获取原生事件。

使用合成事件目的

  • 方便事件统一管理
  • 进行浏览器兼容,实现更好的跨平台
  • 避免垃圾回收:事件对象可能会被频繁创建和回收,因此 React 引入事件池,在事件池中获取或释放事件对象。即 React 事件对象不会被释放掉,而是存放进一个数组中,当事件触发,就从这个数组中弹出,避免频繁地去创建和销毁(垃圾回收) 。

合成事件原生事件区别

命名方式不同:原生事件命名为纯小写,合成事件命名用小驼峰。
事件处理函数写法不同:原生事件中函数为字符串,合成事件里为函数。
阻止默认行为方式不同:原生事件中可以返回 false 来阻止默认行为,合成事件里需要显式调用 e.preventDefault() 来阻止。

事件池

合成事件对象池,是 React 事件系统提供的一种性能优化方式。合成事件对象在事件池统一管理,不同类型的合成事件具有不同的事件池。
React 事件池仅支持在 React16 及更早版本中,在 React17 已经不使用事件池。

SyntheticEvent 对象会被放入池中统一管理。这意味着 SyntheticEvent 对象可以被复用,当所有事件处理函数被调用之后,其所有属性都会被置空。例如,以下代码是无效的:

function handleChange(e) {
  // This won't work because the event object gets reused.
  setTimeout(() => {
    console.log(e.target.value); // Too late!
  }, 100);
}

https://zh-hans.legacy.reactjs.org/docs/legacy-event-pooling.html

原生事件和React事件的执行顺序

React 所有事件都挂载在 document 对象上。当真实 DOM 元素触发事件,会冒泡到 document 对象后,再处理 React 事件。
所以会先执行原生事件,然后处理 React 事件,最后真正执行 document 上挂载的事件。

原生事件(阻止冒泡)会阻止合成事件的执行;合成事件(阻止冒泡)不会阻止原生事件的执行。

e.stopPropagation()

e.stopPropagation() 可以阻止合成事件在组件树中的冒泡传播。事件本身还都是在 document 上执行。不能阻止原生事件的冒泡传播。
原生事件中如果执行了 stopPropagation 方法,则会导致其他 React 事件失效。因为所有元素的事件将无法冒泡到document上。

React17事件机制的修改

  • 事件统一绑定container上,ReactDOM.render(app, container);而不是document上,这样好处是有利于微前端的,微前端一个前端系统中可能有多个应用,如果继续采取全部绑定在document上,那么可能多应用下会出现问题。比如如果你在一个 React 子应用的 React 事件中调用了 e.stopPropagation(),无法阻止事件冒泡到外部树,因为真实的事件早已传播到 document。
  • React17 对齐了浏览器原生标准。比如 onScroll 事件不再进行事件冒泡。onFocus 和 onBlur 使用原生 focusin, focusout 合成。
  • React17 取消事件池复用。“它并不会提高现代浏览器的性能,甚至还会使经验丰富的开发者一头雾水” -> React 在旧浏览器中重用了不同事件的事件对象,以提高性能,并将所有事件字段在它们之前设置为 null。在 React 16 及更早版本中,使用者必须调用 e.persist() 才能正确的使用该事件,或者正确读取需要的属性。

在这里插入图片描述

https://zh-hans.legacy.reactjs.org/blog/2020/08/10/react-v17-rc.html

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

数字经济全景解析:数据要素、资源与资产的转化与治理

无极低码 :https://wheart.cn 数字经济全景解析:数据要素、资源与资产的转化与治理—无极低码wheart数字经济全景解析:数据要素、资源与资产的转化与治理https://wheart.cn/so/home?mindex&id67737c2a-ef2f-11ee-8183-525400be6368 为…

【现代企业管理】企业组织结构和组织文化的理论与实践——以华为为例

一、前言 管理是科学和艺术的统一体,它是企业成长的保证。企业管理中,管理者面对的往往不是一个完整的系统,而是各种不具有整体规律性的零碎信息的总和,因此进行信息的整合和研究是管理的重点和关键。 组织管理作为管理的四大职…

RDGCN阅读笔记

Relation-Aware Entity Alignment for Heterogeneous Knowledge Graphs 面向异质知识图谱的关系感知实体对齐 Abstract 实体对齐是从不同的知识图(KGs)中链接具有相同真实世界实体的任务,最近被基于嵌入的方法所主导。这种方法通过学习KG表示来工作,以…

SRS OBS利用RTMP协议实现音视频推拉流;WebRTC 屏幕直播分享工具

一、SRS OBS利用RTMP协议实现音视频推拉流 参考:https://ossrs.net/lts/zh-cn/docs/v5/doc/getting-started 1)docker直接运行SRS服务: docker run --rm -it -p 1935:1935 -p 1985:1985 -p 8080:8080 registry.cn-hangzhou.aliyuncs.co…

Netty组件优化之时间轮

关于任务调度有多种方式实现,常见的像Timer,ScheduledThreadPoolExecutor,以及时间轮 Timer原理 timer底层主要是依靠最小堆排序,把任务封装并存储在一个优先级队列中,这个队列底层还是依靠数组和最小堆排序构成。 Timer timer new Timer();…

JavaAgent 技术原理及实战

JavaAgent 技术原理及实战 1、引子2、JavaAgent 简单示例:方法开始和结束时打印日志2.1 创建 Agent2.2 编写验证 agent 功能的测试类2.2.1 使用JavaAgent 静态加载方式2.2.2 使用 JavaAgent 动态加载方式 2.3、小结 3、JavaAgent3.1 JavaAgent是什么?3.2…

使用Detours进行HOOK

文章目录 Detours介绍Detours配置Detours进行Sleep Hook Detours介绍 Detours是微软研究院开发的一款软件工具,用于Windows平台上的应用程序重定向和修改。 它可以在运行时修改应用程序的执行路径,允许开发人员注入自定义代码来改变应用程序的 行为&…

实验2:CLI的使用与IOS基本命令

1、实验目的 通过本实验可以掌握: CLI的各种工作模式个CLI各种编辑命令“?” 和【Tab】键使用方法IOS基本命令网络设备访问限制查看设备的相关信息 2、实验拓扑 CLI的使用与IOS基本命令使用拓扑如下图所示。 3、实验步骤 (1)CLI模式的切…

docker-compose编排lnmp环境

(1)创建一个目录lnmpcompose [rootlocalhost ~]# tree lnmpcompose lnmpcompose ├── conf │ └── nginx.conf ├── docker-compose.yml └── html ├── index.html ├── mysql.php └── test.php (2)在创建的目…

用ENIGMA-toolbox作图

之前一直使用ggseg呈现结果,最近想试一试其他绘图工具。ENIGMA-toolbox有所了解,绘图功能看起来门槛不高,所以就试着用它呈现一些结果。Matlab版本的ENIGMA-toolbox直接使用就是SurfStat的功能绘图,Python版本的绘图功能应该是根据…

Spring Boot页面国际化

GitHub:SpringBootDemo Gitee:SpringBootDemo 微信公众号: 0 开发环境 JDK:1.8Spring Boot:2.7.18 1 检查配置 确保File -> Settings… -> Editor -> File Encodings 配置中编码为UTF-8,否则…

Python | Leetcode Python题解之第2题两数相加

题目: 题解: # Definition for singly-linked list. # class ListNode: # def __init__(self, val0, nextNone): # self.val val # self.next next class Solution:def addTwoNumbers(self, l1: Optional[ListNode], l2: Optiona…

攻防世界-easyphp

题目信息 题目信息如下&#xff1a; 可以看到&#xff0c;key1和key2的值都为1的时候&#xff0c;才能拿到flag。再网上看&#xff0c;发现key1和key2的值取决于a,b和c的值。 <?php highlight_file(__FILE__); $key1 0; $key2 0;$a $_GET[a]; $b $_GET[b];if(isset($a…

Java编程实战:疫情物资分配系统的设计与实现

✍✍计算机编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java实战 |…

分治——归并排序算法

例题一 解法&#xff08;归并排序&#xff09;&#xff1a; 算法思路&#xff1a; 归并排序的流程充分的体现了「分⽽治之」的思想&#xff0c;⼤体过程分为两步&#xff1a; ◦ 分&#xff1a;将数组⼀分为⼆为两部分&#xff0c;⼀直分解到数组的⻓度为 1 &#xff0c;使…

vulhub打靶记录——driftingbox

文章目录 主机发现端口扫描目录扫描爆破子域名提权总结 主机发现 使用nmap扫描局域网内存活的主机&#xff0c;命令如下&#xff1a; nmap -sP 192.168.56.0/24192.168.56.1&#xff1a;主机IP&#xff1b;192.168.56.100&#xff1a;DHCP服务器IP&#xff1b;192.168.56.101…

回溯算法|39.组合总和

力扣题目链接 class Solution { private:vector<vector<int>> result;vector<int> path;void backtracking(vector<int>& candidates, int target, int sum, int startIndex) {if (sum > target) {return;}if (sum target) {result.push_back…

IDEA 详细设置

详细设置 如何打开详细配置界面 1、显示工具栏 2、选择详细配置菜单或按钮 系统设置 默认启动项目配置 启动IDEA时&#xff0c;默认自动打开上次开发的项目&#xff1f;还是自己选择&#xff1f; 如果去掉Reopen projects on startup前面的对勾&#xff0c;每次启动IDEA就会…

【软件安装教程】IDEA

【软件安装教程】IDEA 系统: Windows11 64位版本: ideaIC-2023.3.6官方地址: Jetbrains网盘地址: 百度网盘 下载 处于成本考虑就直接用社区版了&#xff0c;如果专业版配置过程都一样 安装 双击下载的文件 根据电脑存储选择一个合适的地址后点击下一步 选择配置&#…

鸿蒙OS(ArkTS) 案例:【使用http网络请求框架加载验证码】

需求&#xff1a;加载验证码&#xff1b;1.下载验证码图像文件&#xff1b;2.获取header里面验证码ID 踩坑--踩坑--踩坑 根据文档使用 request.downloadFile 请求&#xff0c;官方示例: // pages/xxx.ets // 将网络资源文件下载到应用文件目录并读取一段内容 import common …