React合成事件及其核心思想详解
相关联Javascript知识
1.JavaScript 的事件流
事件流是 JavaScript 处理事件的机制,它描述了事件从发生到被处理的过程。事件流主要包括两个阶段:捕获阶段和冒泡阶段。在捕获阶段,事件从文档的根元素开始,逐层向下传播到目标元素,这个阶段可以阻止事件到达目标元素。在冒泡阶段,事件从目标元素开始,逐层向上传播到文档的根元素,这个阶段可以对事件进行响应。事件流的顺序是:捕获处理程序 → 目标处理程序 → 冒泡处理程序。
2.JavaScript 事件冒泡和捕获的区别是什么?默认是冒泡还是捕获?
- 区别:
事件冒泡:事件从目标元素开始,逐层向上传播到祖先元素,直到文档的根元素(在浏览器中通常是 document 对象)。
事件捕获:事件从文档的根元素开始,逐层向下传播到目标元素。
- 默认行为:
在 JavaScript 中,事件默认是按照冒泡阶段进行传播的。但是,可以通过在事件监听器中使用 capture 选项或 addEventListener 方法的第三个参数来指定事件在捕获阶段进行传播。
3.什么是 JavaScript 的事件代理?
事件代理(Event Delegation)是一种常用的技术,它利用事件冒泡的原理,将事件监听器添加到父元素上,而不是直接添加到目标元素上。当目标元素触发事件时,事件会冒泡到父元素,父元素上的事件监听器可以捕获并处理该事件。这种方法可以减少事件监听器的数量,提高性能,并且便于管理事件监听器。
1. 什么是合成事件?
React 的合成事件 (SyntheticEvent) 是对原生 DOM 事件的封装,它在所有浏览器中表现一致,用于解决跨浏览器的兼容性问题。它是 React 自身实现的一个轻量级事件系统。
2. 核心思想
React 合成事件的核心思想主要包括以下几个方面:
a. 跨浏览器的兼容性
合成事件对原生事件进行了统一封装,屏蔽了不同浏览器之间的行为差异。开发者可以直接使用 React 提供的合成事件,而无需考虑浏览器特性。
b. 事件委托 (Event Delegation)
React 并不将事件处理程序绑定到每个具体的 DOM 节点,而是利用事件委托的机制,将所有事件统一绑定到根节点上(如 document 或 container)。当事件发生时,React 会根据事件对象的 target 属性找到对应的组件进行处理。
优点:
- 减少了事件绑定的数量,提升了性能,尤其是在大量动态 DOM 节点的场景中。
- 易于统一管理和清理事件监听器。
c. 事件池 (Event Pool)
为了提高性能,React 会对事件对象进行对象池化处理。合成事件对象会被重用,事件处理结束后,合成事件的所有属性都会被清空。
function handleClick(event) {console.log(event.type); // 可以正常访问setTimeout(() => {console.log(event.type); // 此时访问将为空,因为事件对象已被复用}, 0);
}
如果需要异步访问事件对象,可以通过 event.persist() 方法保留事件。
function handleClick(event) {event.persist();setTimeout(() => {console.log(event.type); // 异步访问仍然可用}, 0);
}
3. 合成事件与原生事件的对比
| 特性 | React 合成事件 | 原生 JavaScript 事件 | 
|---|---|---|
| 兼容性 | 跨浏览器统一表现 | 需要处理浏览器差异 | 
| 事件绑定 | 事件委托到根节点 | 直接绑定到具体 DOM 节点 | 
| 性能 | 减少事件监听器数量 | 每个绑定的 DOM 节点都有独立监听器 | 
| API | 统一接口(如 onClick,onChange) | 浏览器原生 API | 
| 事件复用 | 事件池机制,需调用 persist() | 不存在复用机制 | 
4. 常见的合成事件
React 提供了一组封装的合成事件,常见事件包括:
- 鼠标事件: onClick,onDoubleClick,onMouseEnter,onMouseLeave
- 键盘事件: onKeyDown,onKeyPress,onKeyUp
- 表单事件: onChange,onInput,onSubmit
- 焦点事件: onFocus,onBlur
- 触摸事件: onTouchStart,onTouchMove,onTouchEnd
- 其他: onScroll,onWheel,onDrag,onDrop
5. 示例代码
import React from "react";function App() {const handleClick = (event) => {console.log("Button clicked!");console.log("Event type:", event.type);event.persist(); // 保留事件setTimeout(() => {console.log("Event type after timeout:", event.type); // 仍可访问}, 1000);};return <button onClick={handleClick}>Click Me</button>;
}export default App;
6. 为什么合成事件更高效?
- 事件委托减少了大量的事件监听器开销。
- 对象池机制复用事件对象,避免频繁创建和销毁,提高了内存使用效率。
- 批量更新:合成事件结合 React 的更新机制(如事务机制、批处理),可以避免不必要的多次重绘。
7. 原生事件与合成事件的混用
在某些情况下,可能需要使用原生事件(如性能优化、与第三方库兼容)。React 合成事件和原生事件可以共存,但需注意它们是独立的事件系统。
function App() {React.useEffect(() => {const handleNativeClick = () => console.log("Native click");document.getElementById("btn").addEventListener("click", handleNativeClick);return () => {document.getElementById("btn").removeEventListener("click", handleNativeClick);};}, []);return <button id="btn">Click Me</button>;
}
总结
React 的合成事件通过事件委托和事件池机制,在保证跨浏览器一致性的同时,优化了性能。虽然它与原生事件有区别,但它简化了开发流程,是 React 框架设计的重要组成部分。
------------------------------------------------------------------------------------------------------------------------------
callBack
React合成事件是React模拟原生DOM事件所有能力的一个事件对象,它是React中较为重要的概念。以下是对React合成事件的详细解析:
一、合成事件的概念
React合成事件(SyntheticEvent)是React根据W3C规范定义的事件,它兼容所有浏览器,并提供了与浏览器原生事件相同的接口。在React中,所有事件都是合成的,而不是原生DOM事件。但可以通过e.nativeEvent属性获取原生DOM事件。
二、合成事件的作用
- 浏览器兼容:React提供的合成事件用来抹平不同浏览器事件对象之间的差异,将不同平台事件模拟成合成事件。
- 性能优化:React采用顶层事件代理机制,将所有事件绑定在document上,通过dispatchEvent来分发事件。这种处理减少了事件注册的次数,并提高了性能。同时,React还引入了事件池来复用事件对象,避免频繁地创建和销毁事件对象(垃圾回收)。
- 统一事件管理:合成事件使得React能够统一管理和处理事件,简化了事件处理的逻辑。
三、合成事件与原生事件的区别
-  命名方式: - 原生事件:命名为纯小写,如onclick、onblur等。
- React事件:命名采用小驼峰式(camelCase),如onClick、onBlur等。
 
- 原生事件:命名为纯小写,如
-  事件处理函数写法: - 原生事件:事件处理函数为字符串。
- React事件:在JSX语法中,传入一个函数作为事件处理函数。
 
-  阻止默认行为: - 原生事件:可以通过返回false方式来阻止默认行为。
- React事件:需要显式使用preventDefault()方法来阻止默认行为。
 
- 原生事件:可以通过返回
-  事件传播: - 原生事件:执行需要经过三个阶段:捕获阶段、目标元素阶段、冒泡阶段。节点上的原生事件的执行是在目标阶段。
- 合成事件:执行是在冒泡阶段。所以原生事件会先合成事件执行,然后再往父节点冒泡。原生事件阻止冒泡会阻止合成事件的触发,而合成事件的阻止冒泡不会影响原生事件。
 
四、合成事件的使用
在React中,可以使用onEventName属性为元素添加事件侦听器,其中eventName是要侦听的事件的名称(例如onClick或onMouseMove)。事件侦听器函数将接收一个合成事件对象作为参数。
jsx复制代码
| function handleClick(event) { | |
| console.log('Button was clicked!'); | |
| } | |
| return <button onClick={handleClick}>Click me</button>; | 
合成事件对象提供了多个有用的属性,如type(事件类型)、target(触发事件的DOM元素)、currentTarget(正在处理事件的DOM元素,通常与target相同,但对于冒泡事件则不同)等。此外,还包含了阻止默认行为的方法,例如preventDefault()和stopPropagation()。
五、合成事件的常见问题
- 事件池:React使用事件池来复用事件对象。当事件触发时,React会从事件池中获取一个事件对象,并在事件处理完成后将其释放回事件池。这避免了频繁地创建和销毁事件对象,提高了性能。
- 事件委托:React采用事件委托的方式来处理事件。它将事件侦听器附加到父元素上,而不是为每个子元素附加单独的侦听器。这可以提高性能,特别是对于具有大量子元素的列表或网格。
- 阻止事件冒泡:在React中,可以使用stopPropagation()方法来阻止事件冒泡。但需要注意的是,阻止合成事件的冒泡不会影响原生事件的传播。
- 异步操作中的事件对象:由于合成事件对象在事件处理函数调用后被回收,因此应避免在异步操作中访问这些对象。如果需要在异步操作中使用事件对象的信息,应该在事件处理函数内部将其保存到另一个变量中。
六、最佳实践
- 使用箭头函数作为事件处理程序:这有助于绑定事件处理程序函数中的this上下文。但需要注意的是,使用箭头函数会在每次渲染时创建一个新的函数实例,这可能会影响性能。在性能敏感的场合,可以考虑使用其他方法来绑定this上下文。
- 使用事件委派来提高性能:对于具有大量子元素的列表或网格,将事件侦听器附加到父元素上可以提高性能。
- 小心使用preventDefault()和stopPropagation():仅在绝对必要时使用这些方法,因为它们可以中断默认浏览器行为并影响事件传播。
综上所述,React合成事件是React中处理事件的一种重要机制。它提供了跨浏览器兼容性、性能优化和统一事件管理等优点。在使用合成事件时,需要遵循最佳实践并注意常见问题以确保代码的正确性和性能。
相关文章:
React合成事件及其核心思想详解
相关联Javascript知识 1.JavaScript 的事件流 事件流是 JavaScript 处理事件的机制,它描述了事件从发生到被处理的过程。事件流主要包括两个阶段:捕获阶段和冒泡阶段。在捕获阶段,事件从文档的根元素开始,逐层向下传播到目标元素&…...
 
Datawhale模型减肥秘籍Tasking之模型量化
Datawhale模型减肥秘籍Tasking之模型量化 什么是量化?为什么量化?量化基本方法基于k-means的量化线性量化 训练后量化量化粒度动态量化参数的计算 ( Cliping )指数移动平均(EMA)Min-MaxKL 量化均方误差(MSE)…...
 
在云服务器搭建 Docker
操作场景 本文档介绍如何在腾讯云云服务器上搭建和使用 Docker。本文适用于熟悉 Linux 操作系统,刚开始使用腾讯云云服务器的开发者。如需了解更多关于 Docker 相关信息,请参见 Docker 官方。 说明: Windows Subsystem for Linuxÿ…...
 
Redis 的代理类注入失败,连不上 redis
在测试 redis 是否成功连接时,发现 bean 没有被创建成功,导致报错 根据报错提示,需要我们添加依赖: <dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId>&l…...
 
版本控制【Git Bash】【Gitee】
目录 一、什么是版本控制? 二、版本控制的种类: 1、本地版本控制 2、集中版本控制 3、分布式版本控制 三、下载Git Bash 四、Git Bash 配置 五、Git Bash使用 1、切换目录:cd 2.查看当前文件路径:pwd 3.列出当前目录下文件…...
 
Neo4j Desktop 和 Neo4j Community Edition 区别
Neo4j Desktop 和 Neo4j Community Edition 的主要区别在于它们的用途、功能以及安装和管理方式。以下是这两者的详细对比: 1. Neo4j Desktop Neo4j Desktop 是一个图形化的桌面应用程序,主要为开发人员和个人使用提供了一个便捷的环境来安装、管理和运…...
 
使用uniapp开发微信小程序使用uni_modules导致主包文件过大,无法发布的解决方法
在使用uniapp开发微信小程序时候,过多的引入uni_modules的组件库,会导致主包文件过大,导致无法上传微信小程序,主包要求大小不超过1.5MB.分包大小每个不能超过2M。 解决方法:分包。 1.对每个除了主页面navbar的页面进…...
 
HarmonyOS NEXT应用元服务开发Intents Kit(意图框架服务)事件推荐开发者测试
意图框架向开发者提供真机测试能力,即开发者可连接设备进行调测。开发者完成代码开发之后,功能正式上架应用市场前,可以在HarmonyOS NEXT设备上面进行自验证,打磨体验。真机测试分为三个步骤:基础信息提供,…...
GD32F103 实践-- MCU编译运行
编译 打开固件库示例工程:在SDK路径下找到固件库示例工程,路径通常是SDK\GD32F10x_Firmware_Library_Template\Keil5_project\Project 选择芯片型号:根据你的MCU型号选择,例如GD32F103RCT6 修改宏定义:根据MCU型号修…...
 
SQL复杂数据类型处理
背景 数据处理中,经常碰到复杂数据类型,需要将他们进行解析才能利用。 复杂数据类型 1、MAP结构转为列 WITH tmp AS ( SELECT {"Users":{"4418":{"UserId":4418,"Score":0,"IsStudent":true},&q…...
 
ROS第九梯:ROS+VSCode+Python+C++自定义消息发布和订阅
首先,Python版本的ROS项目和C++版本的ROS项目前期创建功能包的步骤基本一致,具体可参考第二章。 费一步:新建msg文件 在功能包(data_input)目录下创建一个msg文件夹,并在msg文件夹下创建一个名为Box的msg文件,具体如下图所示: 该msg文件为一个用于描述3D Box的文件,…...
 
【Linux】指令 + 压缩与解压
Linux 一.Linux基本指令1.grep2.zip和unzip1.Linux中的压缩文件发送Windows中2.Linux中接收Windows中压缩文件 3.tar(重要)1.Linux与Linux互传压缩文件 4.bc5.uname 二.Linux相关知识点1.Linux常用热键2.关机操作 一.Linux基本指令 1.grep 行文本过滤工…...
 
力扣(leetcode)题目总结——动态规划篇
leetcode 经典题分类 链表数组字符串哈希表二分法双指针滑动窗口递归/回溯动态规划二叉树辅助栈 本系列专栏:点击进入 leetcode题目分类 关注走一波 前言:本系列文章初衷是为了按类别整理出力扣(leetcode)最经典题目,…...
 
数据仓库数据湖湖仓一体解决方案
一、资料介绍 数据仓库与数据湖是现代数据管理的两大核心概念。数据仓库是结构化的数据存储仓库,用于支持企业的决策分析,其数据经过清洗、整合,以固定的模式存储,适合复杂查询。数据湖则是一个集中存储大量原始数据的存储库&…...
 
微信小程序 最新获取用户头像以及用户名
一.在小程序改版为了安全起见 使用用户填写来获取头像以及用户名 二.代码实现 <view class"login_box"><!-- 头像 --><view class"avator_box"><button wx:if"{{ !userInfo.avatarUrl }}" class"avatorbtn" op…...
 
无人机在森林中的应用!
一、森林资源调查 无人机可以利用遥感技术快速获取所需区域高精度的空间遥感信息,对森林图斑进行精确区划。相较于传统手段,无人机调查具有低成本、高效率、高时效的特点,尤其在地理环境条件不好的区域,调查人员无法或难以到达的…...
 
Seatunnel解决Excel中无法将数字类型转换成字符串类型以及源码打包
需求 需要实现将Excel中的数字类型的单元格像数据库中字符串类型的字段中推送 问题原因 Seatunnel在读取字段类型的时候都是使用强转的形式去获取数据的 假如说数据类型不一样的话直接强转就会报错 修改位置 org/apache/seatunnel/api/table/type/SeaTunnelRow.java org…...
 
在阿里云快速启动Appsmith搭建前端页面
什么是Appsmith Appsmith是一个开源的低代码开发平台,它使得开发者能够快速地构建内部工具、业务管理系统、CRM系统等。Appsmith通过提供一系列预建的UI组件(如表格、图表、表单等),以及对数据库、API调用的直接支持,…...
 
「51媒体」:企业成长助推器
传媒如春雨,润物细无声,大家好,我是51媒体网胡老师。 「51媒体」(51meiti media PR)作为国内具有影响力的媒体邀约服务商,确实在助力企业成长方面发挥着重要作用。以下是对「51媒体」的详细介绍࿰…...
 
安全、便捷、效率高,明达边缘计算网关助力制药装备企业远程调机
随着药厂对设备运维需求的增长,制药装备企业需要在提高运维效率的同时,降低人工及差旅成本。制药装备因其数据具有高度的保密性,要求运维工程师提供安全可靠的远程调试方式。本案例介绍了明达技术MBox20系列5口WIFI通用网关在制药装备上的应用…...
HTML 语义化
目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案: 语义化标签: <header>:页头<nav>:导航<main>:主要内容<article>&#x…...
 
深入剖析AI大模型:大模型时代的 Prompt 工程全解析
今天聊的内容,我认为是AI开发里面非常重要的内容。它在AI开发里无处不在,当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗",或者让翻译模型 "将这段合同翻译成商务日语" 时,输入的这句话就是 Prompt。…...
 
树莓派超全系列教程文档--(61)树莓派摄像头高级使用方法
树莓派摄像头高级使用方法 配置通过调谐文件来调整相机行为 使用多个摄像头安装 libcam 和 rpicam-apps依赖关系开发包 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 配置 大多数用例自动工作,无需更改相机配置。但是,一…...
 
VB.net复制Ntag213卡写入UID
本示例使用的发卡器:https://item.taobao.com/item.htm?ftt&id615391857885 一、读取旧Ntag卡的UID和数据 Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click轻松读卡技术支持:网站:Dim i, j As IntegerDim cardidhex, …...
线程同步:确保多线程程序的安全与高效!
全文目录: 开篇语前序前言第一部分:线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分:synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分ÿ…...
 
【大模型RAG】Docker 一键部署 Milvus 完整攻略
本文概要 Milvus 2.5 Stand-alone 版可通过 Docker 在几分钟内完成安装;只需暴露 19530(gRPC)与 9091(HTTP/WebUI)两个端口,即可让本地电脑通过 PyMilvus 或浏览器访问远程 Linux 服务器上的 Milvus。下面…...
 
Python爬虫(一):爬虫伪装
一、网站防爬机制概述 在当今互联网环境中,具有一定规模或盈利性质的网站几乎都实施了各种防爬措施。这些措施主要分为两大类: 身份验证机制:直接将未经授权的爬虫阻挡在外反爬技术体系:通过各种技术手段增加爬虫获取数据的难度…...
 
关键领域软件测试的突围之路:如何破解安全与效率的平衡难题
在数字化浪潮席卷全球的今天,软件系统已成为国家关键领域的核心战斗力。不同于普通商业软件,这些承载着国家安全使命的软件系统面临着前所未有的质量挑战——如何在确保绝对安全的前提下,实现高效测试与快速迭代?这一命题正考验着…...
 
2025季度云服务器排行榜
在全球云服务器市场,各厂商的排名和地位并非一成不变,而是由其独特的优势、战略布局和市场适应性共同决定的。以下是根据2025年市场趋势,对主要云服务器厂商在排行榜中占据重要位置的原因和优势进行深度分析: 一、全球“三巨头”…...
 
免费数学几何作图web平台
光锐软件免费数学工具,maths,数学制图,数学作图,几何作图,几何,AR开发,AR教育,增强现实,软件公司,XR,MR,VR,虚拟仿真,虚拟现实,混合现实,教育科技产品,职业模拟培训,高保真VR场景,结构互动课件,元宇宙http://xaglare.c…...
