提问:
-
为什么要一起挂在document上?
-
合成事件背后的原理?
为什么挂在document上
-
统一管控。
-
冒泡机制的原因,提高性能。
-
在底层抹平了浏览器之间的差异,在上层面向开发者暴露统一的、稳定的、与 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 提供了一种按需绑定的机制,并不是所有的事件都是一次性绑定到document上的。
事件系统
主要做了两件事,1.事件绑定 2. 事件触发
多次调用click,document 上的事件监听执行几次?
执行一次。
即使多次调用了同一事件监听,在document上也会只执行一次注册。
这是用来注册的函数,这个listener回调并不是指某一个回调,而是一个具体的事件分发函数。
其实就是dispatchEvent方法。
事件存储
回调函数的存储采用键值对的方式。key 是组件的唯一标识 id,value 对应的就是事件的回调函数。
方便查找到对应的组件并做后续处理。
事件触发/执行
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