某次被问到 React事件机制的问题,关于这一块我确实不怎么清楚,因为平时大部分工作都是用 Vue,对于 React的熟悉程度只限于会

Vue通过编译模板,解析出事件指令,将事件和事件回调附加到 vnode tree上,在 patch过程中的创建阶段和更新阶段都会对这个 vnode tree进行处理,拿到每个 vnode上附加的事件信息,就可以调用原生 DOM API对相应事件进行注册或移除,流程还是比较清晰的,而React则是单独实现了一套事件机制

在 react源码的 react-dom/src/events/ReactBrowserEventEmitter.js文件的开头,看了一些源码和一些注释太多了也没有仔细研究,然后从网上也是总结了别人的一些总结如下

1.React事件使用了事件委托的机制,一般事件委托的作用都是为了减少页面的注册事件数量,减少内存开销,优化浏览器性能,React这么做也是有这么一个目的,除此之外,也是为了能够更好的管理事件,实际上,React中所有的事件最后都是被委托到了 document这个顶级DOM上

2.既然所有的事件都被委托到了 document上,那么肯定有一套管理机制,所有的事件都是以一种先进先出的队列方式进行触发与回调

3.既然都已经接管事件了,那么不对事件做些额外的事情未免有些浪费,于是 React中就存在了自己的 合成事件(SyntheticEvent),合成事件由对应的 EventPlugin负责合成,不同类型的事件由不同的 plugin合成,例如 SimpleEvent Plugin、TapEvent Plugin等

4.为了进一步提升事件的性能,使用了 EventPluginHub这个东西来负责合成事件对象的创建和销毁

这里也是有三个面试相关的题,和答案

一、组件基础

1. React 事件机制

<div onClick={this.handleClick.bind(this)}>点我</div>

React并不是将click事件绑定到了div的真实DOM上,而是在document处监听了所有的事件,当事件发生并且冒泡到document处的时候,React将事件内容封装并交由真正的处理函数运行。这样的方式不仅仅减少了内存的消耗,还能在组件挂在销毁时统一订阅和移除事件。

JSX 上写的事件并没有绑定在对应的真实 DOM 上,而是通过事件代理的方式,将所有的事件都统一绑定在了 document 上。这样的方式不仅减少了内存消耗,还能在组件挂载销毁时统一订阅和移除事件。

另外冒泡到 document 上的事件也不是原生浏览器事件,而是 React 自己实现的合成事件(SyntheticEvent)。因此我们如果不想要事件冒泡的话,调用 event.stopPropagation 是无效的,而应该调用 event.preventDefault。

实现合成事件的目的如下:

合成事件首先抹平了浏览器之间的兼容问题,另外这是一个跨浏览器原生事件包装器,赋予了跨浏览器开发的能力;

对于原生浏览器事件来说,浏览器会给监听器创建一个事件对象。如果你有很多的事件监听,那么就需要分配很多的事件对象,造成高额的内存分配问题。但是对于合成事件来说,有一个事件池专门来管理它们的创建和销毁,当事件需要被使用时,就会从池子中复用对象,事件回调结束后,就会销毁事件对象上的属性,从而便于下次复用事件对象。

二, React的事件和普通的HTML事件有什么不同?

区别:

对于事件名称命名方式,原生事件为全小写,react 事件采用小驼峰;

对于事件函数处理语法,原生事件为字符串,react 事件为函数;

react 事件不能采用 return false 的方式来阻止浏览器的默认行为,而必须要地明确地调用preventDefault()来阻止默认行为。

合成事件是 react 模拟原生 DOM 事件所有能力的一个事件对象,其优点如下:

兼容所有浏览器,更好的跨平台;

将事件统一存放在一个数组,避免频繁的新增与删除(垃圾回收)。

方便 react 统一管理和事务机制。

事件的执行顺序为原生事件先执行,合成事件后执行,合成事件会冒泡绑定到 document 上,所以尽量避免原生事件与合成事件混用,如果原生事件阻止冒泡,可能会导致合成事件不执行,因为需要冒泡到document 上合成事件才会执行。

3. React 组件中怎么做事件代理?它的原理是什么?

React基于Virtual DOM实现了一个SyntheticEvent层(合成事件层),定义的事件处理器会接收到一个合成事件对象的实例,它符合W3C标准,且与原生的浏览器事件拥有同样的接口,支持冒泡机制,所有的事件都自动绑定在最外层上。

在React底层,主要对合成事件做了两件事:

事件委派: React会把所有的事件绑定到结构的最外层,使用统一的事件监听器,这个事件监听器上维持了一个映射来保存所有组件内部事件监听和处理函数。

自动绑定: React组件中,每个方法的上下文都会指向该组件的实例,即自动绑定this为当前组件。

总结

  • 统一的分发函数dispatchEvent。
  • React的事件对象是合成对象(SyntheticEvent)。
  • 几乎所有的事件都委托到document,达到性能优化的目的。
  • 合成事件与原生事件混用要注意React的事件基本都是委托到document。

最后给大家奉上源码解析的文章链接

https://juejin.cn/post/6844903700423507976?share_token=296b0c62-98f7-4b5f-9ccd-316b6fb59067

React基础之事件机制相关推荐

  1. react的事件机制

    好久没写博客了,前段时间太忙以至于平时的积累都记录在内网的wiki里,趁着这几天有空,将这段时间所积累的干货慢慢的分享出来,如果内容有不正确的地方,欢迎纠正. 本博客大概介绍一下react的事件机制, ...

  2. React Native 手势触摸事件机制详解(基础篇)

          欢迎大家关注[跨平台开发那些事]公众号,定期推送跨平台开发技术实践.        源码已开源到Github,详细代码可以查看:<React Native 触摸事件代码实践>. ...

  3. React Native 手势触摸事件机制详解(进阶篇)

    源码已开源到Github,详细代码可以查看:<React Native 触摸事件代码实践>. 在基础篇,对RN中的触摸事件做了详细的介绍.相信大家对于触摸事件流程机制有了更为清晰的认识.没 ...

  4. 探究react的事件机制(合成事件)

    一.react的事件机制 react自身实现了一套事件机制,包括事件的注册.事件的存储.事件的合成及执行等. react 的所有事件并没有绑定到具体的dom节点上而是绑定在了document 上,然后 ...

  5. React事件机制 - 源码概览(下)

    上篇文档 React事件机制 - 源码概览(上)说到了事件执行阶段的构造合成事件部分,本文接着继续往下分析 批处理合成事件 入口是 runEventsInBatch // runEventsInBat ...

  6. Javascript基础与面向对象基础~第六讲 Javascript中的事件机制

    回到目录 事件机制,在JS中感觉很容易让人接受,一个鼠标被按下时会发生一些事情,一个键盘的键被抬起时同样可以发生一些事情,这种比喻很容易让人接受,不是吗,呵呵. 下面我将JS中几个主要的事件说一下,然 ...

  7. React基础篇(六)React中绑定事件的注意点

    本小节讲述在 React 中为 button 设置点击事件的注意点 1 前言 在 React 中,事件的名称都是 React 中提供的,因此名称的首字母必须厉害 例如 onClick onMouseO ...

  8. jquery 监听td点击事件_React 事件 | 1. React 中的事件委托

    说到 React 的事件,也算是 React 的一个非常有亮点的优化,它在原生事件体系的基础上,单独实现了一套事件机制.想要了解这个机制,首先的了解下什么是事件委托以及事件委托的好处. 事件委托 假设 ...

  9. 处理 react_【学习教程】React 中阻止事件冒泡的问题

    来源 | https://www.cnblogs.com/Wayou/p/react_event_issue.html 在正式开始前,先来看看 js 中事件的触发与事件处理器的执行. js 中事件的监 ...

  10. 「前端面试题系列7」Javascript 中的事件机制(从原生到框架)

    前言 这是前端面试题系列的第 7 篇,你可能错过了前面的篇章,可以在这里找到: 理解函数的柯里化 ES6 中箭头函数的用法 this 的原理以及用法 伪类与伪元素的区别及实战 如何实现一个圣杯布局? ...

最新文章

  1. UVa 12012 - Detection of Extraterrestrial(hash)
  2. SQL语句汇总(三)——聚合函数、分组、子查询及组合查询
  3. XenDesktop7-基于SCVMM2012SP1的部署
  4. PAT甲级1121 Damn Single :[C++题解]哈希表、结构体
  5. leetcode之Tow Sum两数之和的三种思路
  6. Server Hard drive mode
  7. 开机发现超级管理员账户不见了
  8. mysql三高讲解(一):1.2 一个sql语句的执行过程
  9. height、clientHeight、scrollHeight、offsetHeight区别
  10. File Finder pro Mac版重复文件查找器使用方法
  11. ESXi7.0 安装 MacOS (ESXi Unlocker 3.0.3)
  12. Go Grpc Jwt身份认证和Gateway集成以及HTTPS双向认证
  13. 网络安全笔记-业务安全
  14. 若依Vue分离版本 RuoYi-Vue管理系统部署
  15. python全案例学习_Python全案例学习与实践
  16. 如何生成二维码?生成二维码其实很简单
  17. 横版过关游戏开发-碰撞检测
  18. 为什么新冠德尔塔毒株如此“危险”?
  19. Android屏幕适配概论:
  20. 全新版大学英语综合教程第一册学习笔记(原文及全文翻译)——6 - What Animals Really Think(动物到底想些什么)

热门文章

  1. 3.25万颗!真正前装上车的激光雷达供应商有哪几家?
  2. 我的OpenBSD配置文件
  3. openbsd系统可以做什么服务器,OpenBSD 3.8 release 架设FTP服务器
  4. ElasticSearch Groovy 沙盒绕过 代码执行漏洞 CVE-2015-1427 漏洞复现
  5. 「网络流 24 题」火星探险问题。
  6. 笔记本电脑连接wifi后突然上不了网解决方法汇总
  7. python怎么群发邮件_小工具:使用python群发邮件
  8. 亚马逊aws申请ses邮件推送攻略
  9. 软件公司使用XPlanner进行敏捷项目计划和进度跟踪管理
  10. 2014微软open day 51CTO讲师、博主、版主~