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

news/2024/4/28 11:25:29/文章来源:https://blog.csdn.net/cherry__yu/article/details/137106628

文章目录

  • 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

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

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

相关文章

有效的数独-java

题目描述: 请你判断一个 9 x 9 的数独是否有效。只需要 根据以下规则 ,验证已经填入的数字是否有效即可。 数字 1-9 在每一行只能出现一次。数字 1-9 在每一列只能出现一次。数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。(请参考示例图&#…

什么是RISC-V?开源 ISA 如何重塑未来的处理器设计

RISC-V代表了处理器架构的范式转变,特点是其开源模型简化了设计理念并促进了全球community-driven的开发。RISC-V导致了处理器技术发展前进方式的重大转变,提供了一个不受传统复杂性阻碍的全新视角。 RISC-V起源于加州大学伯克利分校的学术起点&#xff…

RabbitMQ 实验消费原始队列消息, 拒绝(reject)投递死信交换机过程

如果你想通过 RabbitMQ 的死信队列功能实现消费者拒绝消息投递到死信交换机的行为,你可以按照以下步骤操作: 创建原始队列,并将其绑定到一个交换机上: export RABBITMQ_SERVER127.0.0.1 export RABBITMQ_PORT5672 export RAB…

uniApp使用XR-Frame创建3D场景(6)播放模型动画

上篇文章讲述了如何将XR-Frame作为子组件集成到uniApp中使用 这篇我们讲解播放模型动画 先看源码 <xr-scene render-system"alpha:true" bind:ready"handleReady"> <xr-node visible"{{sec6}}"><xr-light type"ambient&qu…

Mac 装 虚拟机 vmware、centos7等

vmware&#xff1a; https://www.vmware.com/products/fusion.html centos7 清华镜像&#xff1a; 暂时没有官方的 m1 arm架构镜像 centos7 链接: https://pan.baidu.com/s/1oZw1cLyl6Uo3lAD2_FqfEw?pwdzjt4 提取码: zjt4 复制这段内容后打开百度网盘手机App&#xff0c;操…

ida调试技巧-通过修改zf寄存器的值绕过简单反调试

参考本篇->OllyDbg笔记-对标志寄存器中ZF的理解&#xff08;逆向方面&#xff09;_零标志位zf怎么判断-CSDN博客 不想看也没关系&#xff0c;蒟蒻博主概述一下&#xff0c;总之&#xff0c;在机器执行汇编指令时&#xff0c;标志&#xff08;flag&#xff09;寄存器中的一个…

(4)(4.3) Kogger Sonar

文章目录 前言 1 推荐硬件 2 配置回声探测仪模块 3 连接ArduPilot硬件 4 参数说明 前言 KOGGER 声纳(KOGGER Sonar)是一款结构紧凑、成本低廉的水下回声测深仪模块&#xff0c;带有 UART 接口&#xff0c;电源电压为 5-14v。 1 推荐硬件 CP210x USB->UART 转换器和安装…

深度学习故障诊断实战 | 数据预处理之基于滑动窗的数据样本增强

前言 本期给大家分享介绍如何基于滑动窗方法进行数据样本增强 背景 深度学习模型训练需要大量的样本。在故障诊断领域&#xff0c;每个类别大都会达到300个样本。但是在实际公开数据集中&#xff0c;以CWRU数据集为例&#xff0c;每个类别只有24组数据&#xff0c;这明显是不…

HelpLook AI ChatBot:自定义Prompts综合指南

AI问答机器人&#xff08;AI Chatbot&#xff09;日益在各行业普及&#xff0c;但回答准确率的不足仍是其面临的痛点。用户在与AI问答机器人的互动中常发现&#xff0c;机器人难以完全理解和准确回答复杂问题。HelpLook可以通过自定义提示词&#xff08;Prompts&#xff09;和集…

【VMware Workstation】公司所有主机和虚拟机ip互通,以及虚拟机目录迁移

文章目录 1、场景2、环境3、实战3.1、所有主机和虚拟机ip互通Stage 1 : 【虚拟机】设置为桥接模式Stage 2 : 【虚拟机】设置ipStage 3 : 【路由器】ARP 静态绑定MACStage 3-1 ping 路由器 ipStage 3-2 【静态绑定】虚拟机查看mac地址Stage 3-3 【静态绑定】路由器ARP 静态绑定 …

eclipse自动跳到console 解决办法

eclipse启动服务后&#xff0c;想看一些properties信息或者别的&#xff0c;但老是自动跳转到console页面&#xff0c;下面是解决办法&#xff1a; Eclipse中按照如下顺序找到设置菜单的位置&#xff1a; Window — Preferences — Run/Debug — Console 找到以下两项&#xf…

阿里云CentOS7安装ZooKeeper单机模式

前提条件 阿里云CentOS7安装好jdk&#xff0c;可参 hadoop安装 的jdk安装部分 下载 [hadoopnode1 ~]$ cd softinstall [hadoopnode1 softinstall]$ wget https://archive.apache.org/dist/zookeeper/zookeeper-3.7.1/apache-zookeeper-3.7.1-bin.tar.gz 解压 [hadoopnode1 …

【论文阅读】FlipCAM:高分辨率遥感影像弱监督建筑物提取的特征级翻转增强方法

【论文阅读】FlipCAM&#xff1a;高分辨率遥感影像弱监督建筑物提取的特征级翻转增强方法 文章目录 【论文阅读】FlipCAM&#xff1a;高分辨率遥感影像弱监督建筑物提取的特征级翻转增强方法一、介绍二、方法2.1 准备2.2 一致性的架构2.3 SAM模块2.4 建筑提取模式 三、实验结果…

网络工程师实验命令(华为数通HCIA)

VRP系统的基本操作 dis version #查看设备版本信息 sys #进入系统视图 system-name R1 #改设备名字为R1进入接口配置IP地址 int g0/0/0 ip address 192.168.1.1 255.255.255.0 #配置接口地址为192.168.1.1/255.255.255.0 ip address 192.168.1.2 24 sub #此…

【C语言】预处理常见知识详解(宏详解)

文章目录 1、预定义符号2、define2.1 define 定义常量2.2 define 定义宏 3、#和##3.1 **#**3.2 **##** 4、条件编译&#xff08;开关&#xff09; 1、预定义符号 在C语言中内置了一些预定义符号&#xff0c;可以直接使用&#xff0c;这些符号实在预处理期间处理的&#xff0c;…

云蜜罐技术(德迅猎鹰)诞生

数字化程度高且高价值信息密集的行业&#xff0c;如金融、能源、互联网、政府、教育、医疗、军工等行业&#xff0c;面对日益规模化、专业化的网络攻击&#xff0c;渐渐不再满足于一味的防守加固。除了巩固防线之外&#xff0c;他们愈发看重主动出击、感知更大范围内的攻击&…

uniapp调用腾讯图形验证码,兼容h5、APP(安卓)

因项目要兼容安卓APP&#xff0c;所以使用webview做成了一个组件 新建hybrid文件夹&#xff0c;创建要在webview引入的html文件 <!DOCTYPE html> <html><head><meta charset"utf-8" /><meta name"viewport"content"widt…

Jenkins拉取github项目相关问题

1.私有仓库问题 1.1如果你的仓库是私有的&#xff0c;21年起github就不支持账号密码的方式拉取代码了 那么就需要在github上面创建一个token (classic) 然后在Jenkins代码设置那里 然后应该就可以顺利打包了。 2.找不到pom&#xff08;多了一层文件夹&#xff09;问题 解…

Svg Flow Editor 原生svg流程图编辑器(四)

系列文章 Svg Flow Editor 原生svg流程图编辑器&#xff08;一&#xff09; Svg Flow Editor 原生svg流程图编辑器&#xff08;二&#xff09; Svg Flow Editor 原生svg流程图编辑器&#xff08;三&#xff09; Svg Flow Editor 原生svg流程图编辑器&#xff08;四&#xf…

边缘计算与云计算总结

一. EdgeGallery 简介 MEC场景下的EdgeGallery是让资源边缘化&#xff0c;实时完成移动网络边缘的业务处理&#xff0c;MEC场景下的EdgeGallery让开发者能更便捷地使用 5G 网络能力&#xff0c;让5G能力在边缘触手可及。 EdgeGallery是由华为、信通院、中国移动、中国联通、…