一、合成事件
react 基于 vitrual dom 实现了 syntheticEvent (合成事件),react 事件处理器接收到一个 syntheticEvent 对象,syntheticEvent 和原生浏览器事件一样拥有同样的接口,也支持事件冒泡机制。可以通过 stopPropgation 和 preventDefault 中断。如果需要访问原生事件对象,可以使用 nativeEvent 属性。
二、实现机制
react 的事件机制利用了事件委托机制。事件并没有绑定在真实的 dom 节点上,而是把事件都绑定在结构的最外层 document,使用一个统一的事件监听器。所有的事件都由这个监听器统一分发。
组件挂载和更新时,会将绑定的事件分门别类的放进一个叫做EventPluginHub的事件池里。事件触发时,根据事件产生的Event对象找到触发事件的组件,再通过组件标识和事件类型从事件池里找到对应的事件监听回调,然后执行相关的监听函数。
三、react 中怎么使用原生
在 didmount 中,也可以对真实的 dom 节点,进行原生的事件绑定,原生事件的绑定要在 unmount 时进行解绑,以防止内存泄漏
但 syntheticEvent 的 stopPropgation 无法阻止原生事件的冒泡。反之原生事件的阻止冒泡行为,却可以阻止合成事件的传播。所以尽量不要原生与合成事件混用,如必须混用,又无法阻止冒泡,使用 e.target 进行判断。
四、异步回调怎么使用 syntheticEvent
React追求极致的性能。在合成事件机制里,一旦事件监听回调被执行,合成事件对象就会被销毁,异步的回调执行的时候合成事件对象早就被销毁了。解决方法,就是执行下面的 event.persist(); 用于通知 react 不需要回收,
五、与原生对比
由于原生的捕获机制并不常用,且具有 ie 的不兼容问题, react 仅实现了冒泡机制。既没有兼容问题,而且使用委托机制只有 document 节点上才有 DOM 事件也节约了内存。
六、事件执行
找到事件触发的 DOM 和 React Component,从该 React Component,调用 findParent 方法,遍历得到所有父组件,存在数组中。从该组件直到最后一个父组件,根据之前事件存储,用 React 事件名 + 组件 key,找到对应绑定回调方法。