React合成事件详解

 更新时间:2021年05月03日 10:47:42   作者:humblegod  
这篇文章主要介绍了React合成事件的相关资料,帮助大家更好的理解和学习使用React,感兴趣的朋友可以了解下

react合成事件指的是react用js模拟了一个Dom事件流。(fiber树模拟Dom树结构) 合成事件的事件流在fiber树中发生捕获和冒泡。

从点击输入框开始

当你点击input输入框,react在根节点(注1)监听到focus事件(注2)(注3)。

如何从原生事件找到对应的虚拟Dom?

此时,react得到的信息只有原生事件对象(nativeEvent)。react通过nativeEvent对应的Dom(eventTarget),沿着Dom树向上找到距离该eventTarget最近的被react管理的Dom节点(注4)(注5),并获得对应的fiber A。

接着通过事件插件(注6),创建合成事件(注7)A。合成事件A被react视为模拟事件流中的事件源,fiber A被react视为事件目标。

合成事件流?

从fiber A出发向上(直到顶层fiber HostComponent为止)收集所有的host类型的fiber。 然后将收集到的fiber数组,从后向前(捕获),再从前向后(冒泡)遍历。每次遍历,会收集(注8)当前遍历项fiber节点的绑定的focus事件。之后(事件插件完成后,即合成事件生成好了)会按照收集的顺序执行foucs回调。 react就是这样模拟了事件流。

扩展

点击输入框引起多个事件

除了focus外,也触发了其他的事件--click等。react在根节点对不同类型的事件进行了监听,每监听到一种事件就会派发一次,多种类型的事件,会派发多次。 点击输入框,会先后触发focus和click。当focus事件的派发完后,就会派发click事件。 每次某个事件派发结束,会处理待处理的同步任务队列(flushSyncCallBackQueue)。

意料之外的render?

在NoMode模式下,多次派发事件且每个事件都改变了状态(如调用setState),则对应组件会被render多次。 在本例中,点击input输入框,如果给input绑定了focus事件和click事件并且事件回调都调用setState,input将会render两次。

为什么react中的input设置value后成为受控组件?

react中,在input设置了value属性的条件下,无论在输入框中输入什么,输入框的值都不会改变。除非你改变了input组件的state。 react在处理完模拟事件流后,会调用方法将一些意外的效果重置。 例如该场景,在input中输入了一个值,input输入框会出现你输入的值,但马上input的值会被对应的fiber的value属性更新(finishEventHander 重置受控组件)。 如果没有给input设置value则会忽略。

为什么合成事件属性有时无法访问?

因为react在事件流(捕获到冒泡)完后就将合成事件对象释放(SyntheticEvent.prototype.destructor 将合成事件对象的属性重置)。

react如何模拟事件的阻止冒泡、阻止默认行为?

react按照事件流顺序执行回调,在执行前会检查当前合成事件对象是否处于阻止冒泡的状态,如果是,则终止事件流。 react的合成事件对象原型对原生函数进行增强。对原生事件方法的阻止冒泡、阻止默认行为进行了封装(内部也调用原生事件的方法)。

注释

注1:根节点,在 react-v16 为 document ,在 react-v17 为挂载容器Dom
注2:focus事件并不是冒泡事件,react对非冒泡事件在捕获阶段监听
注3:根节点对所有事件进行了监听,除了特别例外submit、reset、invalid和媒体事件等
注4:react将fiber树挂载到Dom树上时,每个宿主(host)类型fiber节点与Dom节点一一对应,并链接
注5:向上查找是因为可能子Dom节点并不是被react管理的,如第三库滚动插件等
注6:为了模拟Dom事件,react进行的补充
注7:react内部一个构造函数的实例,合成事件的部分属性来源于nativeEvent。合成事件与fiber关联
注8:收集而不是执行。因为react针对某一类型事件的做了批处理

以上就是React合成事件详解的详细内容,更多关于React合成事件的资料请关注脚本之家其它相关文章!

相关文章

  • 如何将你的AngularJS1.x应用迁移至React的方法

    如何将你的AngularJS1.x应用迁移至React的方法

    本篇文章主要介绍了如何将你的AngularJS1.x应用迁移至React的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-02-02
  • react-beautiful-dnd 实现组件拖拽功能

    react-beautiful-dnd 实现组件拖拽功能

    这篇文章主要介绍了react-beautiful-dnd 实现组件拖拽功能,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-08-08
  • React hooks如何清除定时器并验证效果

    React hooks如何清除定时器并验证效果

    在React中,通过自定义Hook useTimeHook实现定时器的启动与清除,在App组件中使用Clock组件展示当前时间,利用useEffect钩子在组件挂载时启动定时器,同时确保组件卸载时清除定时器,避免内存泄露,这种方式简化了状态管理和副作用的处理
    2024-10-10
  • 解决React报错Property 'value' does not exist on type EventTarget

    解决React报错Property 'value' does not exist on 

    这篇文章主要为大家介绍了React报错Property 'value' does not exist on type EventTarget的解决方法,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-12-12
  • 关于React Native报Cannot initialize a parameter of type''NSArray<id<RCTBridgeModule>>错误(解决方案)

    关于React Native报Cannot initialize a parameter of type''NSArra

    这篇文章主要介绍了关于React Native报Cannot initialize a parameter of type'NSArray<id<RCTBridgeModule>>错误,本文给大家分享解决方案,需要的朋友可以参考下
    2021-05-05
  • React中Redux核心原理深入分析

    React中Redux核心原理深入分析

    这篇文章主要介绍了如何在React中Redux原理,目前redux在react中使用是最多的,所以我们需要将之前编写的redux代码,融入到react当中去,本文给大家详细讲解,需要的朋友可以参考下
    2022-11-11
  • react中antd文本框限制输入中文方式

    react中antd文本框限制输入中文方式

    这篇文章主要介绍了react中antd文本框限制输入中文方式详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-06-06
  • react配置代理setupProxy.js无法访问v3.0版本问题

    react配置代理setupProxy.js无法访问v3.0版本问题

    这篇文章主要介绍了react配置代理setupProxy.js无法访问v3.0版本问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-07-07
  • React实现双向绑定示例代码

    React实现双向绑定示例代码

    这篇文章给大家介绍了在React中如何实现双向绑定,文中给出了示例代码,对大家的理解与学习很有帮助,有需要的朋友下面来一起看看吧。
    2016-09-09
  • react配置antd按需加载的使用

    react配置antd按需加载的使用

    这篇文章主要介绍了react配置antd按需加载的使用,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-02-02

最新评论