React 事件机制和原生 DOM 事件流有什么区别

devtools/2024/12/22 16:50:27/

发现宝藏

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。【宝藏入口】。


React 的事件机制与原生 DOM 事件流在设计和实现上有一些显著的区别。了解这些区别有助于我们更好地理解 React 是如何管理事件的,并且能更高效地使用它。

1. 事件绑定方式

  • 原生 DOM 事件流
    在原生 JavaScript 中,事件是通过直接绑定到 DOM 元素上实现的。例如:

    <button id="myButton">Click Me</button>
    <script>javascript">document.getElementById("myButton").addEventListener("click", function() {alert("Button clicked!");});
    </script>
    

    事件处理程序通过 addEventListeneronclick 等方式绑定到 DOM 元素上,且每个元素的事件监听器都是独立的。

  • React 事件机制
    React 的事件系统使用 事件委托 的方式,所有的事件处理程序都统一绑定到 根 DOM 元素(通常是 documentroot)。React 会使用一个单一的事件监听器来管理所有组件中的事件。这是为了提升性能,减少不必要的事件监听器数量。React 事件通过 合成事件系统(SyntheticEvent) 来处理。

    例如:

    function MyButton() {const handleClick = () => alert("Button clicked!");return <button onClick={handleClick}>Click Me</button>;
    }
    

    虽然在 JSX 中看起来像是直接在按钮上绑定了事件,但实际上,React 会将所有的事件处理程序集中到根节点,并且利用事件代理来处理事件。

2. 事件流(Event Flow)

事件流包括了三个阶段:捕获阶段(Capturing)、目标阶段(Target)和冒泡阶段(Bubbling)。

  • 原生 DOM 事件流
    原生 DOM 事件流采用的是 冒泡模型,即事件从目标元素开始向上传播到父元素,直到到达根节点。此外,原生 DOM 事件也支持 捕获阶段,即事件从根节点开始向下传播到目标元素。

    • 捕获阶段:事件从根节点开始向下到目标元素(先执行)。
    • 目标阶段:事件在目标元素上触发。
    • 冒泡阶段:事件从目标元素向上传播到根节点。

    你可以通过设置 addEventListener 的第三个参数来控制是使用冒泡阶段还是捕获阶段:

    element.addEventListener('click', handler, true);  // 捕获阶段
    element.addEventListener('click', handler, false); // 冒泡阶段
    
  • React 事件流
    React 默认只支持 冒泡阶段,不支持捕获阶段。React 的事件系统将所有事件处理程序都放在事件冒泡阶段执行,因此 React 中的事件会依次向上传播,直到到达根组件(一般是 documentroot)。React 不直接使用 DOM 的捕获和冒泡机制,而是通过合成事件系统来模拟类似的行为。

3. 事件对象(SyntheticEvent)

  • 原生 DOM 事件对象
    原生 DOM 事件对象是由浏览器创建的原生 JavaScript 对象,包含事件的详细信息,如 event.targetevent.type 等。该对象在事件处理函数中是直接由浏览器传递的。

  • React 合成事件(SyntheticEvent)
    React 在内部使用一个 合成事件系统(SyntheticEvent),它是对浏览器原生事件对象的包装。这个合成事件与原生事件对象有相同的接口(例如:event.targetevent.preventDefault() 等),但是它在 React 内部进行了封装,具有跨浏览器的兼容性。合成事件还可以减少内存泄漏的风险,因为它们在事件处理程序执行后会被池化(被重用),而不是每次都创建新的事件对象。

    示例:

    function MyButton() {const handleClick = (event) => {console.log(event);  // 这里的 event 是 SyntheticEvent};return <button onClick={handleClick}>Click Me</button>;
    }
    

4. 事件委托(Event Delegation)

  • 原生 DOM 事件委托
    在原生 DOM 中,事件委托是通过将事件监听器绑定到父元素来实现的,避免在每个子元素上单独绑定事件。例如:

    document.getElementById("parent").addEventListener("click", function(event) {if (event.target && event.target.matches("button")) {alert("Button clicked!");}
    });
    
  • React 事件委托
    React 默认实现了事件委托,它将所有的事件处理程序绑定到根元素,而不是每个组件的 DOM 元素上。React 通过事件代理的方式提高性能,避免为每个组件和 DOM 元素单独绑定事件监听器。React 会将事件处理委托到 document 或根节点上,再通过事件的传播机制处理到每个具体的事件。

5. 性能优化

  • 原生 DOM 事件
    原生 DOM 中,如果你在多个元素上添加事件监听器(如 addEventListener),每个元素都会有自己的事件监听器。这可能导致性能问题,尤其是当页面中有大量的元素时,因为每个元素都需要独立的事件监听器。

  • React 事件机制
    由于 React 使用了事件委托机制,所有的事件处理程序都被集中在一个单独的事件监听器上,这显著减少了事件监听器的数量,从而提升了性能。这是 React 事件系统的一大优势。

6. 事件池(Event Pooling)

  • 原生 DOM 事件
    原生事件对象会在每个事件触发时创建,事件处理函数执行后,这些事件对象会继续存在,直到垃圾回收机制处理它们。

  • React 合成事件池化
    在 React 中,事件对象是池化的,这意味着每次事件处理完成后,React 会将事件对象归还到事件池中,这样就可以复用这些对象,避免频繁的对象创建和销毁,从而提升性能。

总结

特性原生 DOM 事件React 事件机制
事件绑定直接绑定到 DOM 元素事件委托,统一绑定到根 DOM 元素
事件流捕获、目标、冒泡阶段只支持冒泡阶段
事件对象原生事件对象SyntheticEvent,包装后的事件对象
事件委托手动实现事件委托自动实现事件委托
性能优化每个元素独立绑定事件监听器通过事件委托优化性能
事件池没有池化机制合成事件池化,减少内存使用

React 的事件机制与原生 DOM 事件机制相比,主要通过事件委托、合成事件和池化机制等手段来提升性能和跨浏览器兼容性。它的设计旨在简化开发者的工作,使得在 React 中处理事件更加高效且一致。


http://www.ppmy.cn/devtools/144423.html

相关文章

未来趋势系列 篇五:自主可控科技题材解析和股票梳理

文章目录 系列文章自主可控科技题材分析国产算力信创(信息技术应用创新)华为鸿蒙军工信息化半导体芯片卫星互联网工业软件股票梳理系列文章 未来趋势系列 篇一:AI题材解析和股票梳理 未来趋势系列 篇一(加更):AI医疗题材解析和股票梳理 未来趋势系列 篇二:HBM题材解析和…

本地maven项目打包部署到maven远程私库

目的&#xff1a;在自己的maven项目中&#xff0c;要把当前maven项目部署到maven私库&#xff0c;供其他人引入依赖使用。 首先要确保你当前能访问到你的私库&#xff0c;能拉私库的maven依赖即可。 maven部署命令&#xff1a; mvn deploy:deploy-file -Dmaven.test.skiptrue -…

Flink优化----数据倾斜

目录 判断是否存在数据倾斜 数据倾斜的解决 keyBy 后的聚合操作存在数据倾斜 为什么不能直接用二次聚合来处理 使用 LocalKeyBy 的思想 DataStream API 自定义实现的案例 keyBy 之前发生数据倾斜 keyBy 后的窗口聚合操作存在数据倾斜 实现思路 提交原始案例 提交两阶…

【原生js案例】ajax的简易封装实现后端数据交互

ajax是前端与后端数据库进行交互的最基础的工具&#xff0c;第三方的工具库比如jquery,axios都有对ajax进行第二次的封装&#xff0c;fecth是浏览器原生自带的功能&#xff0c;但是它与ajax还是有区别的&#xff0c;总结如下&#xff1a; ajax与fetch对比 实现效果 代码实现 …

深入解析PCIe地址空间与寄存器机制:从地址映射到TLP生成的完整流程

往期内容 本文章相关专栏往期内容&#xff0c;PCI/PCIe子系统专栏&#xff1a; 嵌入式系统的内存访问和总线通信机制解析、PCI/PCIe引入 深入解析非桥PCI设备的访问和配置方法 PCI桥设备的访问方法、软件角度讲解PCIe设备的硬件结构 深入解析PCIe设备事务层与配置过程 PCIe的三…

Sentinel 学习笔记3-责任链与工作流程

本文属于sentinel学习笔记系列。网上看到吴就业老师的专栏&#xff0c;原文地址如下&#xff1a; https://blog.csdn.net/baidu_28523317/category_10400605.html 上一篇梳理了概念与核心类&#xff1a;Sentinel 学习笔记2- 概念与核心类介绍-CSDN博客 补一个点&#xff1a;…

【pytorch】多层感知机

将许多全连接层堆叠在一起。每一层都输出到上面的层&#xff0c;直到生成最后的输出。我们可以把前L−1层看作表示&#xff0c;把最后一层看作线性预测器。这种架构通常称为多层感知机通常缩写为MLP。 1 激活函数 激活函数&#xff08;activation function&#xff09;通过计…

【腾讯云】AI驱动TDSQL-C Serveress 数据库技术实战营-如何是从0到1体验电商可视化分析小助手得统计功能,一句话就能输出目标统计图

欢迎来到《小5讲堂》 这是《腾讯云》系列文章&#xff0c;每篇文章将以博主理解的角度展开讲解。 温馨提示&#xff1a;博主能力有限&#xff0c;理解水平有限&#xff0c;若有不对之处望指正&#xff01; 目录 背景效果图流程图创建数据库基本信息数据库配置设置密码控制台开启…