结合源码吃透React事件机制原理01-事件机制初步认识与验证
前言这是React事件机制的第一篇文章,主要内容有:表象理解、验证、意义与思考。外观理解首先回顾一下对react事件机制的基本理解。React本身实现了一套自己的事件机制,包括事件注册、事件合成、事件冒泡、事件派发等,虽然和原来的有所不同,但也是基于浏览器的事件机制下完成的服务器。我们都知道react的所有事件并不是绑定到具体的dom节点而是绑定到document,然后由一个统一的事件处理器处理,这也是基于浏览器的事件机制(冒泡),所有的Node事件都会在文档。以上是基于对react事件的基本理解,那么这个理解正确吗?我们可以通过简单的方式验证一下。Verification验证内容:所有事件都注册到元素的顶层——文档上节点的事件由一个统一的入口处理。为了方便,直接通过cli创建一个项目。代码如下:componentDidMount(){document.getElementById('btn-reactandnative').addEventListener('click',(e)=>{console.log('native+reactevent:nativeeventexecution');});}handleNativeAndReact=(e)=>{console.log('native+reactevent:当前正在执行的reactevent');}handleClick=(e)=>{console.log('按钮点击');}render(){return反应事件!!!
反应事件native+reactevent
}代码中两个按钮绑定了一个合成事件,btn绑定了一个原生事件#btn-reactandnative分开。然后查看chrome的控制台,可以看到元素上的注册事件。简单验证后,可以看到所有的事件都按照不同的事件类型绑定到了document上。触发函数统一为dispatchEvent。试想一下,如果一个节点同时绑定了合成事件和原生事件,关闭冒泡后的执行关系是怎样的?事实上,这里已经阅读了答案。我们现在根据现有知识分析这种关系。因为合成事件的触发是基于浏览器的事件机制实现的,它通过冒泡机制冒泡到最顶层元素,然后由dispatchEvent处理。这是我得出的结论:防止冒泡的本机事件肯定会阻止合成事件触发。阻止合成事件的冒泡不会影响本机事件。为什么?先回忆一下浏览器事件机制浏览器事件的执行需要经历三个阶段,捕获阶段-目标元素阶段-冒泡阶段。节点上nativeevent的执行是在target阶段,而syntheticevent的执行是在冒泡阶段,所以nativeevent会先执行syntheticevent,然后再冒泡到父节点。既然原生的都防止冒泡了,那合成呢?嗯,轮到synthetic的被挡住冒泡了,native的会执行吗?当然会。因为本机事件在合成事件之前执行,所以只有合成事件被阻止在合成事件内部冒泡。(我就不贴代码了)所以得出结论:nativeevents(防止冒泡)会阻止syntheticevents的执行Syntheticevents(防止冒泡)不会阻止nativeevents的执行最好不要混用二是避免出现一些奇怪的问题。React自己做这么多有什么意义?我的理解是1.减少内存消耗,提高性能,不需要注册那么多事件,一种事件在文档上只注册一次2.统一规范,解决ie事件兼容性问题,简化事件逻辑3.是的开发者友好的思考React既然为我们做了这么多事情,那么它背后的机制是什么?事件是如何注册的,事件是如何触发的,冒泡机制是如何实现的?后续文章请看.....更多精彩内容请关注我的公众号-前端张大发