当前位置: 首页 > news >正文

探索 JavaScript 事件机制(四):React 合成事件系统

前言

在前端开发中,事件处理是不可或缺的一部分。在众多的前端框架中,React 凭借其高效和灵活性受到众多开发者的喜爱。React 的事件处理系统,即“合成事件系统”,是其性能优化的一大亮点。
本文将带你深入浅出地探索 React 的合成事件系统,了解其原理和优势。

合成事件系统简介

React 的合成事件系统(Synthetic Event System)是对浏览器原生事件的封装和优化。它不仅统一了不同浏览器的事件模型,还提供了更高效的事件处理机制。通过合成事件,React 可以实现更好的性能和跨浏览器兼容性。

为什么需要合成事件?

  1. 跨浏览器兼容性:不同浏览器的事件模型存在差异,React 的合成事件系统可以屏蔽这些差异,提供一致的事件处理接口。
  2. 性能优化:React 使用事件委托机制,将所有事件处理器绑定到根节点上,从而减少内存占用和频繁的 DOM 操作。
  3. 统一接口:通过合成事件,React 提供了一套统一的事件对象,开发者可以更方便地处理各种事件。

事件委托机制

在传统的事件处理方式中,我们通常会为每个需要处理事件的元素单独绑定事件处理器。而在 React 中,合成事件系统采用了事件委托机制,将所有的事件处理器统一绑定到应用的根节点上。当事件触发时,事件会冒泡到根节点,再由根节点上的事件处理器统一处理。

事件委托的优势

  1. 降低内存消耗:只需要在根节点上维护一个事件处理器,避免为每个元素单独分配内存。
  2. 减少 DOM 操作:通过统一的事件处理机制,可以减少频繁的 DOM 操作,提高性能。
  3. 方便管理:所有事件处理器都集中在根节点上,方便统一管理和调试。

React 合成事件的内部实现

事件池机制

React 为了优化事件处理的性能,引入了事件池(Event Pool)机制。事件池是一个用来复用合成事件对象的池子,避免频繁创建和销毁事件对象,从而减少内存开销和垃圾回收。
在事件触发时,React 从事件池中取出一个合成事件对象,对其进行初始化,并在事件处理完成后,将其重置并放回事件池中。

创建合成事件

React 合成事件是对原生事件的封装,对象包括各种事件类型,例如 SyntheticMouseEvent、SyntheticKeyboardEvent 等。这些合成事件对象统一派生自 SyntheticEvent 基类。

class SyntheticEvent {constructor(dispatchConfig, targetInst, nativeEvent, nativeEventTarget) {this.dispatchConfig = dispatchConfig;this._targetInst = targetInst;this.nativeEvent = nativeEvent;// 根据原生事件对象初始化合成事件对象的属性for (let propName in nativeEvent) {if (!nativeEvent.hasOwnProperty(propName)) continue;this[propName] = nativeEvent[propName];}// 其他初始化逻辑...}preventDefault() {this.defaultPrevented = true;const event = this.nativeEvent;if (event.preventDefault) {event.preventDefault();} else {event.returnValue = false;}}stopPropagation() {const event = this.nativeEvent;if (event.stopPropagation) {event.stopPropagation();} else {event.cancelBubble = true;}}// 重置合成事件对象destructor() {for (let propName in this) {if (this.hasOwnProperty(propName)) {this[propName] = null;}}}
}

事件调度与分发

React 使用事件调度器(Event Dispatcher)来管理和分发事件。当事件触发时,React 会捕获到该事件,并通过事件调度器查找对应的事件处理函数,进行调用。

事件调度分为三个阶段:

  1. 捕获阶段(Capture Phase):从根节点到目标元素逐步捕获事件。
  2. 目标阶段(Target Phase):在目标元素上触发事件处理函数。
  3. 冒泡阶段(Bubble Phase):从目标元素逐步冒泡回根节点,触发冒泡事件处理函数。
function dispatchEvent(event, topLevelType, targetInst) {const nativeEvent = event.nativeEvent;// 构建合成事件对象const syntheticEvent = new SyntheticEvent(topLevelType,targetInst,nativeEvent,nativeEvent.target);// 捕获阶段调度事件traverseTwoPhase(targetInst, accumulateDirectionalDispatches, syntheticEvent);// 目标阶段调度事件accumulateDispatches(targetInst, syntheticEvent);// 冒泡阶段调度事件traverseTwoPhase(targetInst, accumulateDirectionalDispatches, syntheticEvent, true);// 处理事件队列runEventQueueInBatch(syntheticEvent);
}

React 合成事件处理流程

事件处理器的绑定

在 React 中,我们通过 onEventName 属性绑定事件处理器。例如:

<button onClick={this.handleClick}>Click Me</button>

编译后的代码中,React 会将 handleClick 函数绑定到事件调度器中,并在事件触发时调用。

事件处理器的执行

当事件触发时,React 会根据事件类型和目标元素,从事件调度器中找到对应的事件处理函数,并依次调用。这其中涉及事件捕获和冒泡机制。

事件的清理

在事件处理完成后,React 会重置合成事件对象并将其放回事件池中,等待下次复用。这一过程减少了垃圾回收的频率,提高了性能。

总结

React 合成事件系统通过事件池机制、事件调度与分发机制,实现了高效的事件处理和跨浏览器兼容性。理解其内部实现原理,有助于我们更好地优化和调试 React 应用。

相关文章:

探索 JavaScript 事件机制(四):React 合成事件系统

前言 在前端开发中&#xff0c;事件处理是不可或缺的一部分。在众多的前端框架中&#xff0c;React 凭借其高效和灵活性受到众多开发者的喜爱。React 的事件处理系统&#xff0c;即“合成事件系统”&#xff0c;是其性能优化的一大亮点。 本文将带你深入浅出地探索 React 的合…...

openlayers 封装加载本地geojson数据 - vue3

Geojson数据是矢量数据&#xff0c;主要是点、线、面数据集合 Geojson数据获取&#xff1a;DataV.GeoAtlas地理小工具系列 实现代码如下&#xff1a; import {ref,toRaw} from vue; import { Vector as VectorLayer } from ol/layer.js; import { Vector as VectorSource } fr…...

手机号码携号转网查询接口-在线手机号码携号转网查询-手机号码携号转网查询API

接口简介&#xff1a;通过手机号精准查询该号码转网前及转网后所归属运营商 可查询号码是否为虚拟手机号 可查询到号码归属地信息 高准确率&#xff0c;实时查询运营商数据库 多用于营销场景&#xff0c;如运营商业务办理、客户信息查询、携号转网、电话营销等 接口地址&#x…...

yolo目标检测和姿态识别和目标追踪

要检测摄像头画面中有多少人&#xff0c;人一排排坐着&#xff0c;像教室那样。由于摄像头高度和角度的原因&#xff0c;有的人会被遮挡。 yolo v5 首先需要下载yolo v5官方代码&#xff0c;可以克隆或下载主分支的代码&#xff0c;或者下载release中发布的。 简单说一下环境…...

Docker搭建开源Web云桌面操作系统Puter和DaedalOS

文章目录 Puter 操作系统说明基于 Docker 启动 Puter 操作系统拉取镜像运行容器基于 Docker-Compose 启动 Puter操作系统创建目录编写docker-compose.yml运行在本地直接运行puter操作系统puter界面截图puter个人使用总结构建自己的Puter镜像daedalos基于web的操作系统说明技术特…...

FAQ-为什么交换机发给服务器的日志显示的时间少8小时

问题描述 配置交换机向日志服务器发送日志&#xff0c;在交换机上面查看日志显示的时间比日志服务器显示的时间快8个小时 解决方案 根据公司全球化整改的要求&#xff0c;syslog默认发送的是UTC时间。 当前设备上配置了时区UTC8&#xff0c;因此&#xff0c;设备上显示的本地…...

[表达式]真假计算

题目描述 有一棵树&#xff0c;不一定是二叉树。 所有叶子节点都是 True 或者 False。 对于从上往下奇数层的非叶子节点是 and&#xff0c;偶数层非叶子节点为 or。 树上每个节点的值是所有孩子节点的值进行该节点的运算操作。 判断一棵树能否砍掉&#xff0c;最快的方法就是从…...

记录一次线上环境svchost.exe antimalware service executable 进程占用CPU过高问题

博主介绍&#xff1a; 大家好&#xff0c;我是想成为Super的Yuperman&#xff0c;互联网宇宙厂经验&#xff0c;17年医疗健康行业的码拉松奔跑者&#xff0c;曾担任技术专家、架构师、研发总监负责和主导多个应用架构。 技术范围&#xff1a; 目前专注java体系&#xff0c;有多…...

Docker 部署 EMQX 一分钟极速部署

部署 EMQX ( Docker ) [Step 1] : 拉取 EMQX 镜像 docker pull emqx/emqx:latest[Step 2] : 创建目录 ➡️ 创建容器 ➡️ 拷贝文件 ➡️ 授权文件 ➡️ 删除容器 # 创建目录 mkdir -p /data/emqx/{etc,data,log}# 创建容器 docker run -d --name emqx -p 1883:1883 -p 1808…...

STL-常用容器-list

1list基本概念 **功能&#xff1a;**将数据进行链式存储 链表&#xff08;list&#xff09;是一种物理存储单元上非连续的存储结构&#xff0c;数据元素的逻辑顺序是通过链表中的指针链接实现的 链表的组成&#xff1a;链表由一系列结点组成 结点的组成&#xff1a;一个是存储…...

Lambda 架构

Lambda架构是一种用于构建可扩展、容错和实时数据处理系统的架构模式。 它由三个主要部分组成&#xff1a;批处理层&#xff08;Batch Layer&#xff09;、实时层&#xff08;Speed Layer&#xff09;和服务层&#xff08;Serving Layer&#xff09;。 Lambda架构旨在结合批处…...

Windows电脑设置网络唤醒(Wake-on-LAN)

1. 启用 Windows 电脑的 Wake-on-LAN 功能 首先&#xff0c;你需要确保你的 Windows 电脑支持并启用了 Wake-on-LAN&#xff1a; BIOS/UEFI 设置(具体看自己电脑主板如何设置): 启动 Windows 电脑&#xff0c;进入 BIOS/UEFI 设置。找到网络适配器相关的设置&#xff0c;启用 …...

前端项目构建流程

1. 需求分析 目标&#xff1a;明确项目目标、核心功能和用户需求。 产品需求讨论&#xff1a; 与产品经理、客户、业务部门讨论项目的需求和目标&#xff0c;理解产品的功能、业务流程以及用户需求。定义用户角色&#xff08;Persona&#xff09;&#xff0c;明确不同用户的功…...

支持国密算法的数字证书-国密SSL证书详解

在互联网中&#xff0c;数字证书作为标志通讯各方身份信息的数字认证而存在&#xff0c;常见的数字证书大都采用国际算法&#xff0c;比如RSA算法、ECC算法、SHA2算法等。随着我国加强网络安全技术自主可控的大趋势&#xff0c;也出现了支持国密算法的数字证书-国密SSL证书。那…...

【EndNote使用教程】创建文献库、导入文献、文献分类

1、创建文献库 打开“EndNote”&#xff0c;点击“文件”&#xff0c;点击“新建”&#xff0c;选择保存文件路径。 2、导入文献 &#xff08;1&#xff09;可以选择导入电脑上的PDF文件&#xff0c;如下图所示。 &#xff08;2&#xff09; 也可以选择直接在浏览器网页上面直…...

双十一电容笔选哪个好?!西圣、益博思、吉玛仕电容笔实测对比!

当数码测评博主几年年&#xff0c;我也实测过不下10款电容笔了&#xff0c;对电容笔这个品类也算是半个内行人了。提到电容笔&#xff0c;在平替品牌的追逐中&#xff0c;西圣、益博思、吉玛仕这三款作为国货黑马一直备受瞩目&#xff0c;综合各大电商平台的销量榜、好评口碑榜…...

房地产网络安全:主要风险及缓解建议

房地产行业已开始数字化转型&#xff0c;因此极易受到网络犯罪的攻击。潜在风险的清单很长&#xff1a;从客户敏感信息的数据泄露到勒索软件攻击&#xff0c;网络犯罪分子将房地产公司视为其所携带的所有类型敏感信息的高价值目标。 在本文中&#xff0c;我们将探讨房地产领域…...

玩转大模型的第一步——提示词(Prompt)工程【抛砖篇】

前言 AI大模型提示词工程&#xff0c;又名 LLM prompts Project&#xff0c;指的是在使用大型语言模型&#xff08;如OpenAI的GPT系列&#xff09;时&#xff0c;用于引导模型生成特定响应的输入&#xff0c;是在使用AI大模型过程中非常重要的一个环节&#xff0c;是模型生成文…...

火山引擎数据飞轮线上研讨会即将开启,助力消费品牌双十一造爆款

随着双十一的临近&#xff0c;各大品牌方的备战工作已进入紧张而有序的倒计时阶段。这场持续十多年的电商大促&#xff0c;对消费者来说是购物狂欢节&#xff0c;对各大品牌方来说&#xff0c;则是更是品牌实力与策略的比拼。面对日益激烈的市场竞争&#xff0c;如何更好地撬动…...

【python实战】利用代理ip爬取Alibaba海外版数据

引言 在跨境电商的业务场景中&#xff0c;数据采集是分析市场、了解竞争对手以及优化经营策略的重要环节。然而&#xff0c;随着越来越多企业依赖数据驱动决策&#xff0c;许多跨境电商平台为了保护自身数据&#xff0c;采取了更严格的防护措施。这些平台通过屏蔽大陆IP地址或部…...

FFMPEG录屏(20)--- 枚举macOS下的窗口和屏幕列表,并获取名称缩略图等信息

在 macOS 下获取可屏幕共享的窗口和屏幕 在 macOS 下&#xff0c;我们可以通过使用 Core Graphics 和 Cocoa 框架来获取当前系统中可屏幕共享的窗口和屏幕信息。本文将详细介绍如何获取窗口和屏幕的 ID、标题、坐标、进程图标和缩略图等信息。 前提条件 在开始之前&#xff…...

Redis 命令集 (超级详细)

目录 Redis 常用命令集 string类型 hash类型 list类型 set类型 zset类型 bitmap 类型 geo 类型 GEOADD (添加地理位置的坐标) GEOPOS (获取地理位置的坐标) GEODIST (计算两个位置之间的距离) GEOHASH (返回一个或多个位置对象的 geohash 值) GEORADIUS (根据用户…...

Spring Cloud --- GateWay和Sentinel集成实现服务限流

pom添加依赖 <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId> </dependency> <dependency><groupId>com.alibaba.csp</groupId><artifactId>s…...

python excel如何转成json,并且如何解决excel转成json时中文汉字乱码的问题

1.解决excel转成json时中文汉字乱码的问题 真的好久没有打开这个博客也好久没有想起来记录一下问题了&#xff0c;今天将表格测试集转成json格式的时候遇到了汉字都变成了乱码的问题&#xff0c;虽然这不是个大问题&#xff0c;但是编码问题挺烦人的&#xff0c;乱码之后像下图…...

【MySQL】实战篇—数据库设计与实现:根据需求设计数据库架构

在设计数据库架构时&#xff0c;开发者需要遵循一系列步骤&#xff0c;以确保数据库能够高效、可靠地满足系统需求。以下是设计数据库架构的理论知识和步骤说明。 1. 需求分析 需求分析是数据库设计的第一步&#xff0c;旨在理解系统的功能需求和数据需求。通过与利益相关者&…...

[Python学习日记-53] Python 中的正则表达式模块 —— re

[Python学习日记-53] Python 中的正则表达式模块 —— re 简介 re 模块 练习 简介 我们在编程的时候经常会遇到想在一段文字当中找出电话号码、身份证号、身高、年龄之类的信息&#xff0c;就像下面的数据一样 # 文件名&#xff1a;美丽学姐联系方式.txt 姓名 地区 …...

Unity编辑器 连接不到SteamVR问题记录

问题表现&#xff1a;之前正常的工程&#xff0c;某天打开后运行&#xff0c;在SteamVR未打开时&#xff0c;Unity工程运行后无法调用起来Steam VR&#xff0c;无任何反应&#xff0c;但用其他软件则可以调用起来SteamVR&#xff0c;并且运行正常&#xff0c;在重装了XR的一些插…...

nginx 日志配置笔记

Nginx 的日志配置非常重要&#xff0c;它可以帮助你记录服务器的访问情况、错误信息等&#xff0c;便于后续的分析和故障排查。Nginx 的日志配置主要包括访问日志&#xff08;access log&#xff09;和错误日志&#xff08;error log&#xff09;。 1、访问日志&#xff08;Ac…...

Java中的接口是什么?如何定义接口?

1、Java中的接口是什么&#xff1f;如何定义接口&#xff1f; 在Java中&#xff0c;接口是一种引用类型&#xff0c;它定义了一组方法的契约&#xff0c;但不包含实现。接口定义了方法签名&#xff0c;但不提供方法的实现细节。Java中的接口用于实现多态性和代码的抽象化。 在…...

​8.13TB高清卫星影像更新(WGS84坐标投影)

最近对WGS84版的高清卫星影像数据进行了一次更新&#xff0c;并基于更新区域生成了相应的接图表。 8.13TB高清卫星影像更新 本次数据更新了14820个离线包&#xff0c;共8.13TB大小&#xff0c;主要更新目标区域为中国东南区域。 更新范围接图表一 更新范围接图表二 更新范围…...

wordpress首页添加幻灯片/网上培训

这是一个2019年你成为前端&#xff0c;后端或全栈开发者的进阶指南: 你不需要学习所有的技术成为一个web开发者 这个指南只是通过简单分类列出了技术选项 我将从我的经验和参考中给出建议 首选我们会介绍通用的知识, 最后介绍2019年的Web的一些趋势 视频地址&#xff1a; …...

兰州手机网站制作公司/北京seo专业团队

基于springboot在线投票系统 摘 要 随着全球Internet的迅猛发展和计算机应用的普及&#xff0c;特别是近几年无线网络的广阔覆盖以及无线终端设备的爆炸式增长&#xff0c;使得人们能够随时随地的访问网络&#xff0c;以获取最新信息、参与网络活动、和他人在线互动。为了能及时…...

一键查询注册过的网站/网络推广都有哪些方式

一、用 python 进行微信好友分析 1、使用到的库 &#xff08;1&#xff09;wxpy&#xff1a;初始化微信机器人 &#xff08;2&#xff09;openpyxl&#xff1a;保存微信好友数据为Excel表格 &#xff08;3&#xff09; pyecharts&#xff1a;生成可视化的地图 &#xff08;4&am…...

wordpress多级索引/使用 ahrefs 进行 seo 分析

Qt中有这么多类的事件,我们怎么样比较简便的处理每个事件呢?设想,如果是每个事件都对应同一个事件处理器,在该事件处理器中对不同的事件进行分类处理,这样的弊端有两点:第一,导致该事件处理器过于臃肿复杂;第二,这样不便于扩展,当系统新增加事件类型或者是我们需要使…...

我要自学网app/厦门seo外包

我在去年Teched上的课程视频录像&#xff0c;最终获得了整个Teched期间分值排名Top 5的课程。过去了一年时间&#xff0c;当年讲课的录像翻起来看似乎仍不过时。在开始之前再多说两句&#xff1a;从我的角度来看&#xff0c;整个课程是Teched 2012 《60分钟构建私有云 》课程的…...

济南企业网站制/网络营销与直播电商专升本

在现代工程领域&#xff0c;CAD软件是必不可少的伙伴。无论是机械、建筑、电子工程等领域&#xff0c;CAD软件都是设计和制造过程中的关键要素。 然而&#xff0c;在不同阶段和不同领域使用CAD软件的人员&#xff0c;往往会使用不同版本的CAD软件。这就会导致在不同人员之间交…...