React 合成事件

提问:

  1. 为什么要一起挂在document上?

  2. 合成事件背后的原理?

为什么挂在document上

  1. 统一管控。

  2. 冒泡机制的原因,提高性能。

  3. 在底层抹平了浏览器之间的差异,在上层面向开发者暴露统一的、稳定的、与 DOM 原生事件相同的事件接口

17是挂载在root上的。

为什么要从document改成 root

这么做的原因是什么呢?

在 React 17 以前,所有的事件会被附加到 document 上,并为它建一个处理器,当 DOM 事件触发时,会向上冒泡,一直到 document 级别,也就是附加事件处理器的地方,事件会得到响应。

如果页面上有多个 React 版本,事件都会被附加在 document 上。这时嵌套的 React 树调用 e.stopPropagation() 停止了事件冒泡,外部的树仍会接收到该事件,这就使嵌套不同版本的 React 难以实现。

为什么外部的树还会接收到该事件?

因为阻止合成事件间的冒泡,才用e.stopPropagation();

阻止合成事件与最外层document上的事件间的冒泡,用e.nativeEvent.stopImmediatePropagation();

e.nativeEvent 是合成事件保存了原生事件的引用。

React 合成事件
image.png

React 提供了一种按需绑定的机制,并不是所有的事件都是一次性绑定到document上的。

事件系统

主要做了两件事,1.事件绑定 2. 事件触发

多次调用click,document 上的事件监听执行几次?

执行一次。

React 合成事件
123123123.png

即使多次调用了同一事件监听,在document上也会只执行一次注册。

React 合成事件
统一分发函数.png

这是用来注册的函数,这个listener回调并不是指某一个回调,而是一个具体的事件分发函数。

其实就是dispatchEvent方法。

事件存储

回调函数的存储采用键值对的方式。key 是组件的唯一标识 id,value 对应的就是事件的回调函数。

React 合成事件
123123123213123.png

方便查找到对应的组件并做后续处理。

事件触发/执行

React 的事件触发只发生在DOM的冒泡阶段。

ReactEventListener.dispatchEvent会对事件进行分发,根据之前存储的事件类型(type)组件标识(key)找到触发事件的组件。

获取到触发这个事件的元素,遍历这个元素的所有父元素,依次对每一级元素进行处理。构造合成事件,将每一级的合成事件存储在 eventQueue事件队列中,然后批量执行存储的回调函数,回调函数的执行分为两步:

第一步是将所有的合成事件放到事件队列里面。

第二步是逐个执行(React合成事件的冒泡并不是真的冒泡,而是eventQueue的遍历模拟出来的)

简单来说,处理的就是之前事件存储的键值对。找到这个事件元素-》遍历父元素,构造合成事件-> 用一个队列存起来 -》 然后批量执行。

react事件和原生事件可以混用吗?

不可以,因为e.stopPropagation 会阻止原生事件。意味着无法冒泡到document,导致react 事件失效。无法分发执行合成事件队列。

本文转自 https://juejin.cn/post/7087032480737755167,如有侵权,请联系删除。


版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/20464.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!