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

React和原生事件的区别

一、核心差异对比表

维度原生事件React 事件
绑定语法HTML 属性(onclick)或 DOM API(addEventListenerJSX 中使用驼峰式属性(onClick
绑定位置直接绑定到具体 DOM 元素统一委托到根节点(React 17 及以前到 document,React 18 到容器)
事件对象原生 Event 对象,不同浏览器实现有差异合成事件 SyntheticEvent,封装原生事件并抹平浏览器差异
传播机制完整的捕获 → 目标 → 冒泡 三阶段表面只有冒泡,捕获需显式声明(如 onClickCapture),React 18 支持完整阶段
阻止传播event.stopPropagation() 阻止整个 DOM 树的传播仅阻止合成事件传播,不影响原生事件
默认行为event.preventDefault() 或 HTML 中返回 false只能使用 event.preventDefault()
this 指向默认指向 DOM 元素,可通过 bind、箭头函数修改默认 undefined,需手动绑定(构造函数、箭头函数或类属性)
触发顺序按 DOM 树层级依次触发原生事件总是先触发,合成事件在冒泡到根节点后触发
性能优化大量绑定时可能导致内存开销大事件委托 + 事件池(复用事件对象),减少监听器数量和内存占用
兼容性需处理浏览器差异(如 IE 的 attachEvent统一 API,自动处理兼容性

二、关键机制详解

1. 事件委托机制
  • 原生事件
    每个元素需单独绑定监听器,大量元素时性能较差

    // 手动为每个按钮绑定事件
    document.querySelectorAll('button').forEach(btn => {btn.addEventListener('click', handleClick);
    });
    
  • React 事件
    所有事件统一委托到根节点,通过事件类型和目标元素匹配处理函数。

    // 所有按钮的点击事件最终由根节点的统一处理器分发
    <button onClick={handleClick}>Click</button>
    
2. 合成事件 SyntheticEvent
  • 跨浏览器封装
    React 将不同浏览器的原生事件封装为统一接口,例如:

    function handleClick(e) {e.preventDefault(); // 兼容所有浏览器的阻止默认行为console.log(e.target); // 标准化的目标元素
    }
    
  • 事件池优化
    React 复用事件对象以减少 GC 压力(React 17 及以前):

    function handleClick(e) {setTimeout(() => {console.log(e.target); // React 17 及以前此处会失效,因事件对象已被重置}, 0);
    }
    
3. 事件传播差异
  • 原生事件

    预览

    <div onclick="console.log('原生冒泡')"><button onclick="console.log('原生目标')">Click</button>
    </div>
    

    传播顺序:buttondiv(冒泡阶段)。

  • React 事件

    <div onClickCapture={() => console.log('React 捕获')}><button onClick={() => console.log('React 冒泡')}>Click</button>
    </div>
    

    React 18 传播顺序:div(捕获) → button(目标) → div(冒泡)。

4. 触发顺序细节

当同时存在原生和合成事件时:

<div onClick={() => console.log('合成事件')} onMouseDown={() => console.log('合成 mousedown')}
><button onclick="console.log('原生 click')" onmousedown="console.log('原生 mousedown')">Click</button>
</div>

点击按钮的触发顺序:

  1. 原生 mousedown → 原生 click → 合成 onMouseDown → 合成 onClick

三、特殊场景对比

1. 混合使用原生与合成事件
class App extends React.Component {componentDidMount() {// 手动绑定原生事件this.buttonRef.current.addEventListener('click', () => {console.log('原生事件');});}render() {return (<button ref={this.buttonRef} onClick={() => console.log('合成事件')}>Click</button>);}
}
  • 原生事件先触发,合成事件后触发。
  • 原生事件的 stopPropagation() 会阻止合成事件触发。
2. 事件池与异步访问

React 17 及以前复用事件对象,异步访问需提前保存属性:

function handleClick(e) {const target = e.target; // 必须提前保存setTimeout(() => {console.log(target); // 正确访问console.log(e.target); // React 17 及以前会失效}, 0);
}

React 18 移除了事件池,可直接异步访问。

四、总结

特性原生事件React 事件
优势直接控制 DOM,适合复杂交互场景跨浏览器一致性,性能优化,代码简洁
劣势兼容性差,大量绑定时性能问题抽象层级高,特殊场景需结合原生事件
适用场景自定义滚动、拖拽等复杂 DOM 操作组件内交互、表单处理等常规场景
http://www.lryc.cn/news/2397684.html

相关文章:

  • Qt creator 设计页面控件认识与了解
  • 命象架构法 02|你的系统有“用神”吗?
  • NVIDIA Mellanox BlueField-2 DPU(Data Processing Unit)智能网卡的调试和使用
  • Tomcat- AJP协议文件读取/命令执行漏洞(幽灵猫复现)详细步骤
  • B1、进度汇报(— 25/05/31)
  • 工作流引擎-11-开源 BPM 项目 jbpm
  • 【Prompt Engineering】摸索出的一些小套路
  • CSS强制div单行显示不换行
  • js的时间循环的讲解
  • Flutter实现不规则瀑布流布局拖拽重排序
  • 【第4章 图像与视频】4.1 图像的绘制
  • 苹果应用开发详细教程(2025最新版)
  • G25-05-31Rust开源项目日报 Top10
  • 2025年主流编程语言全面分析与学习指南
  • window安装nginx
  • ArcGIS Pro裁剪影像
  • [智能算法]蚁群算法原理与TSP问题示例
  • Vue-4-前端框架Vue基础入门之Vue的常用操作
  • ubuntu国内镜像源手动配置
  • 21-CS61B-lab6:java文件操作以及持久化一见
  • ⚡️ Linux 系统安装与配置 Git
  • SpringBoot 自动装配原理深度解析:从源码到实践
  • 【Go语言】Fyne GUI 库使用指南 (面向有经验开发者)
  • Nginx Lua模块(OpenResty)实战:动态化、智能化你的Nginx,实现复杂Web逻辑 (2025)
  • openssl 怎么生成吊销列表
  • Go语言包的组织与导入 -《Go语言实战指南》
  • springboot-响应接收与ioc容器控制反转、Di依赖注入
  • CSP使用严格设置
  • Spring代理工厂类ProxyFactory作用以及实现原理
  • SpringBoot使用MQTT协议简述