React与原生事件:核心差异与性能对比解析

news2025/6/10 4:56:09

💝💝💝欢迎莅临我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。
推荐:「stormsha的主页」👈,「stormsha的知识库」👈持续学习,不断总结,共同进步,为了踏实,做好当下事儿~
非常期待和您一起在这个小小的网络世界里共同探索、学习和成长。💝💝💝 ✨✨ 欢迎订阅本专栏 ✨✨

在这里插入图片描述

💖The Start💖点点关注,收藏不迷路💖

📒文章目录

    • 1. 事件系统基础
      • 1.1 原生DOM事件的工作原理
      • 1.2 React合成事件(SyntheticEvent)概览
    • 2. 核心差异对比
      • 2.1 事件绑定语法
      • 2.2 事件传播控制
      • 2.3 事件委托实现
    • 3. 高级特性与陷阱
      • 3.1 React事件池的注意事项
      • 3.2 混合使用时的冲突
      • 3.3 自定义事件处理
    • 4. 性能优化实践
      • 4.1 避免内联函数
      • 4.2 大规模列表优化
      • 4.3 被动事件监听器
    • 5. 总结


外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

1. 事件系统基础

1.1 原生DOM事件的工作原理

原生DOM事件遵循W3C标准的事件流模型:

document.getElementById('parent').addEventListener('click', () => {
  console.log('捕获阶段');
}, true); // 第三个参数为true表示捕获阶段

document.getElementById('child').addEventListener('click', (event) => {
  console.log('目标阶段');
  event.stopPropagation(); // 阻止事件冒泡
});

document.getElementById('parent').addEventListener('click', () => {
  console.log('冒泡阶段');
});
  • 事件对象包含关键属性:
    • target: 触发事件的原始元素
    • currentTarget: 当前处理事件的元素
    • stopPropagation(): 停止事件传播
  • 绑定方式差异
    <!-- 内联方式(不推荐) -->
    <button onclick="handleClick()">Click</button>
    
    <!-- 标准方式 -->
    <button id="btn">Click</button>
    <script>
      document.getElementById('btn').addEventListener('click', handleClick);
    </script>
    

1.2 React合成事件(SyntheticEvent)概览

React事件系统的核心设计:

class MyComponent extends React.Component {
  handleClick = (e) => {
    console.log(e.nativeEvent); // 访问底层原生事件
    e.persist(); // 从事件池中移除该事件对象
  }

  render() {
    return <button onClick={this.handleClick}>Click</button>;
  }
}

关键特性:

  • 跨浏览器兼容:统一了IE和现代浏览器的事件差异
  • 事件池机制:默认会回收事件对象,异步访问需调用e.persist()
  • 自动绑定this:类组件中无需手动绑定事件处理函数的this指向

2. 核心差异对比

2.1 事件绑定语法

特性原生DOMReact
事件名onclickonClick
事件值字符串函数引用
动态绑定需要手动removeEventListener自动处理绑定/解绑

错误示例:

// ❌ 错误:传递的是函数调用结果而非函数引用
<button onClick={handleClick()}>Click</button>

// ✅ 正确
<button onClick={handleClick}>Click</button>

2.2 事件传播控制

捕获阶段处理差异:

// 原生DOM可监听捕获阶段
div.addEventListener('click', handler, true);

// React需使用特殊属性名
<div onClickCapture={handleCapture}>...</div>

2.3 事件委托实现

原生实现方案:

document.getElementById('list').addEventListener('click', (e) => {
  if (e.target.tagName === 'LI') {
    console.log('List item clicked:', e.target.dataset.id);
  }
});

React的自动委托机制:

  • 所有事件默认委托到document节点
  • 根据组件树结构自动维护事件映射
  • 事件处理器会收到包含组件层级信息的合成事件

3. 高级特性与陷阱

3.1 React事件池的注意事项

典型异步访问问题:

function handleClick(e) {
  setTimeout(() => {
    // ❌ 报错:事件属性已被回收
    console.log(e.clientX); 
    
    // ✅ 解决方案
    e.persist();
    console.log(e.clientX);
  }, 100);
}

3.2 混合使用时的冲突

安全整合第三方库的模式:

useEffect(() => {
  const handleExternalEvent = () => {...};
  
  // 挂载时绑定
  externalLib.on('event', handleExternalEvent);
  
  // 卸载时清理
  return () => externalLib.off('event', handleExternalEvent);
}, []);

3.3 自定义事件处理

React组件间通信方案:

// 父组件
<Child onCustomEvent={data => console.log(data)} />

// 子组件
<button onClick={() => props.onCustomEvent(payload)}>
  Trigger Event
</button>

4. 性能优化实践

4.1 避免内联函数

优化方案对比:

// ❌ 每次渲染创建新函数
<button onClick={() => setCount(count + 1)}>+</button>

// ✅ 类组件方案
class Counter extends React.Component {
  handleClick = () => {
    this.setState(prev => ({ count: prev.count + 1 }));
  }

  render() {
    return <button onClick={this.handleClick}>+</button>;
  }
}

// ✅ 函数组件方案
function Counter() {
  const handleClick = useCallback(() => {
    setCount(prev => prev + 1);
  }, []);
  
  return <button onClick={handleClick}>+</button>;
}

4.2 大规模列表优化

虚拟滚动实现要点:

<FixedSizeList
  height={400}
  itemCount={1000}
  itemSize={50}
>
  {({ index, style }) => (
    <div style={style} onClick={handleClick}>
      Item {index}
    </div>
  )}
</FixedSizeList>

4.3 被动事件监听器

滚动性能优化方案:

useEffect(() => {
  const opts = { passive: true };
  window.addEventListener('scroll', handleScroll, opts);
  return () => window.removeEventListener('scroll', handleScroll, opts);
}, []);

5. 总结

关键差异总结表:

维度原生事件React合成事件
事件命名全小写驼峰命名
事件绑定命令式API声明式JSX
事件对象原生EventSyntheticEvent
事件委托需手动实现自动全局委托
性能优化需手动管理监听器自动处理大部分场景

选型建议:

  • 使用原生事件的场景:
    • 需要精确控制事件捕获阶段
    • 需要处理React未封装的特殊事件(如resizeObserver)
    • 性能敏感的底层交互(如游戏循环)

最佳实践:

  1. 优先使用React的事件系统
  2. 避免在render中创建新的事件处理器
  3. 及时清理手动添加的原生事件监听器
  4. 善用事件委托处理动态内容

🔥🔥🔥道阻且长,行则将至,让我们一起加油吧!🌙🌙🌙

💖The Start💖点点关注,收藏不迷路💖

width=“100%”>



💖The Start💖点点关注,收藏不迷路💖





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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

暴雨新专利解决服务器噪音与性能悖论

6月1日&#xff0c;我国首部数据中心绿色化评价方面国家标准《绿色数据中心评价》正式实施&#xff0c;为我国数据中心的绿色低碳建设提供了明确指引。《评价》首次将噪音控制纳入国家级绿色评价体系&#xff0c;要求从设计隔声结构到运维定期监测实现闭环管控&#xff0c;加速…

Go 语言中的内置运算符

1. 算术运算符 注意&#xff1a; &#xff08;自增&#xff09;和--&#xff08;自减&#xff09;在 Go 语言中是单独的语句&#xff0c;并不是运算符。 package mainimport "fmt"func main() {fmt.Println("103", 103) // 13fmt.Println("10-3…

JS面试常见问题——数据类型篇

这几周在进行系统的复习&#xff0c;这一篇来说一下自己复习的JS数据结构的常见面试题中比较重要的一部分 文章目录 一、JavaScript有哪些数据类型二、数据类型检测的方法1. typeof2. instanceof3. constructor4. Object.prototype.toString.call()5. type null会被判断为Obje…

【靶场】XXE-Lab xxe漏洞

前言 学习xxe漏洞,搭了个XXE-Lab的靶场 一、搭建靶场 现在需要登录,不知道用户名密码,先随便试试抓包 二、判断是否存在xxe漏洞 1.首先登录抓包 看到xml数据解析,由此判断和xxe漏洞有关,但还不确定xxe漏洞是否存在。 2.尝试xxe 漏洞 判断是否存在xxe漏洞 A.send to …

开源项目实战学习之YOLO11:12.6 ultralytics-models-tiny_encoder.py

👉 欢迎关注,了解更多精彩内容 👉 欢迎关注,了解更多精彩内容 👉 欢迎关注,了解更多精彩内容 ultralytics-models-sam 1.sam-modules-tiny_encoder.py2.数据处理流程3.代码架构图(类层次与依赖)blocks.py: 定义模型中的各种模块结构 ,如卷积块、残差块等基础构建…

Python[数据结构及算法 --- 栈]

一.栈的概念 在 Python 中&#xff0c;栈&#xff08;Stack&#xff09;是一种 “ 后进先出&#xff08;LIFO&#xff09;”的数据结构&#xff0c;仅允许在栈顶进行插入&#xff08;push&#xff09;和删除&#xff08;pop&#xff09;操作。 二.栈的抽象数据类型 1.抽象数…

Unity VR/MR开发-开发环境准备

视频讲解链接&#xff1a; 【XR马斯维】UnityVR/MR开发环境准备【UnityVR/MR开发教程--入门】_哔哩哔哩_bilibili

2025-06-08-深度学习网络介绍(语义分割,实例分割,目标检测)

深度学习网络介绍(语义分割,实例分割,目标检测) 前言 在开始这篇文章之前&#xff0c;我们得首先弄明白&#xff0c;什么是图像分割&#xff1f; 我们知道一个图像只不过是许多像素的集合。图像分割分类是对图像中属于特定类别的像素进行分类的过程&#xff0c;即像素级别的…

【Ragflow】26.RagflowPlus(v0.4.0):完善解析逻辑/文档撰写模式全新升级

概述 在历经半个月的间歇性开发后&#xff0c;RagflowPlus再次迎来一轮升级&#xff0c;正式发布v0.4.0。 开源地址&#xff1a;https://github.com/zstar1003/ragflow-plus 更新方法 下载仓库最新代码&#xff1a; git clone https://github.com/zstar1003/ragflow-plus.…

智能照明系统:具备认知能力的“光神经网络”

智能照明系统是物联网技术与传统照明深度融合的产物&#xff0c;其本质是通过感知环境、解析需求、自主决策的闭环控制&#xff0c;重构光与人、空间、环境的关系。这一系统由智能光源、多维传感器、边缘计算单元及云端管理平台构成&#xff0c;形成具备认知能力的“光神经网络…

SpringSecurity+vue通用权限系统

SpringSecurityvue通用权限系统 采用主流的技术栈实现&#xff0c;Mysql数据库&#xff0c;SpringBoot2Mybatis Plus后端&#xff0c;redis缓存&#xff0c;安全框架 SpringSecurity &#xff0c;Vue3.2Element Plus实现后台管理。基于JWT技术实现前后端分离。项目开发同时采 …

短视频时长预估算法调研

weighted LR o d d s T p 1 − p ( 1 − p ) o d d s T p ( T p o d d s ∗ p ) o d d s p o d d s T o d d s odds \frac{Tp}{1-p} \newline (1-p)odds Tp \newline (Tp odds * p) odds \newline p \frac{odds}{T odds} \newline odds1−pTp​(1−p)oddsTp(Tpodds…

设计模式域——软件设计模式全集

摘要 软件设计模式是软件工程领域中经过验证的、可复用的解决方案&#xff0c;旨在解决常见的软件设计问题。它们是软件开发经验的总结&#xff0c;能够帮助开发人员在设计阶段快速找到合适的解决方案&#xff0c;提高代码的可维护性、可扩展性和可复用性。设计模式主要分为三…

FTPS、HTTPS、SMTPS以及WebSockets over TLS的概念及其应用场景

一、什么是FTPS&#xff1f; FTPS&#xff0c;英文全称File Transfer Protocol with support for Transport Layer Security (SSL/TLS)&#xff0c;安全文件传输协议&#xff0c;是一种对常用的文件传输协议(FTP)添加传输层安全(TLS)和安全套接层(SSL)加密协议支持的扩展协议。…

Python 解释器安装全攻略(适用于 Linux / Windows / macOS)

目录 一、Windows安装Python解释器1.1 下载并安装Python解释1.2 测试安装是否成功1.3 设置pip的国内镜像------永久配置 二、macOS安装Python解释器三、Linux下安装Python解释器3.1 Rocky8.10/Rocky9.5安装Python解释器3.2 Ubuntu2204/Ubuntu2404安装Python解释器3.3 设置pip的…

Java多线程从入门到精通

一、基础概念 1.1 进程与线程 进程是指运行中的程序。 比如我们使用浏览器&#xff0c;需要启动这个程序&#xff0c;操作系统会给这个程序分配一定的资源&#xff08;占用内存资源&#xff09;。 线程是CPU调度的基本单位&#xff0c;每个线程执行的都是某一个进程的代码的某…

【芯片仿真中的X值:隐藏的陷阱与应对之道】

在芯片设计的世界里&#xff0c;X值&#xff08;不定态&#xff09;就像一个潜伏的幽灵。它可能让仿真测试顺利通过&#xff0c;却在芯片流片后引发灾难性后果。本文将揭开X值的本质&#xff0c;探讨其危害&#xff0c;并分享高效调试与预防的实战经验。    一、X值的本质与致…

python3GUI--基于PyQt5+DeepSort+YOLOv8智能人员入侵检测系统(详细图文介绍)

文章目录 一&#xff0e;前言二&#xff0e;技术介绍1.PyQt52.DeepSort3.卡尔曼滤波4.YOLOv85.SQLite36.多线程7.入侵人员检测8.ROI区域 三&#xff0e;核心功能1.登录注册1.登录2.注册 2.主界面1.主界面简介2.数据输入3.参数配置4.告警配置5.操作控制台6.核心内容显示区域7.检…

5. TypeScript 类型缩小

在 TypeScript 中&#xff0c;类型缩小&#xff08;Narrowing&#xff09;是指根据特定条件将变量的类型细化为更具体的过程。它帮助开发者编写更精确、更准确的代码&#xff0c;确保变量在运行时只以符合其类型的方式进行处理。 一、instanceof 缩小类型 TypeScript 中的 in…

【QT】qtdesigner中将控件提升为自定义控件后,css设置样式不生效(已解决,图文详情)

目录 0.背景 1.解决思路 2.详细代码 0.背景 实际项目中遇到的问题&#xff0c;描述如下&#xff1a; 我在qtdesigner用界面拖了一个QTableView控件&#xff0c;object name为【tableView_electrode】&#xff0c;然后【提升为】了自定义的类【Steer_Electrode_Table】&…