跳到主要内容

事件机制

如果把所有的事件处理函数都绑定在DOM上,那么在页面响应的时候就会收到影响,导致页面很慢。react为了避免这类DOM事件的滥用,同时可以兼容不同浏览器事件的系统差异,减少了内存消耗,简化了事件逻辑,并最大化的解决了IE等浏览器的不兼容问题

  • React基于浏览器的事件机制自身实现了一套事件机制,包括事件注册、事件的合成、事件冒泡、事件派发等
    • 事件派发:指定事件目标派发一个事件
  • 事件名称命名方式不同,React 事件处理器使用 camelCase(驼峰式命名)而不使用小写命名
  • 虽然合成事件并不是原生 DOM 事件,但它保存了原生 DOM 事件的引用
    • 当你需要访问原生 DOM 事件对象时,可以通过合成事件对象的 e.nativeEvent 属性获取到它
  • React 自己实现了这么一套事件机制,它在 DOM 事件体系基础上做了改进,减少了内存的消耗,并且最大程度上解决了 IE 等浏览器的不兼容问题,确保事件在不同浏览器中显示一致的属性

什么是 React 合成事件?​

  • 合成事件是原生 DOM 事件的一种包装,它与原生事件的接口相同,
  • 兼容不同浏览器事件的差异,开发者不用担心事件处理浏览器兼容性问题

合成事件原理/机制​

  • 1、初始化渲染的时候。在根节点监听注册所有原生的DOM事件
  • 2、原生事件被触发的时候,React会根据事件的类型和目标元素,找到对应的FiberNode和事件处理函数,创建相应的合成事件并调用事件处理函数

为什么要用合成事件而不直接用原生 DOM 事件?​

  • 兼容不同浏览器事件的差异 和跨平台
  • 方便react来统一事件管理机制
  • 减少内存消耗,使用对象池来管理合成事件对象的创建和销毁

如果把所有的事件处理函数都绑定在DOM上,那么在页面响应的时候就会收到影响,导致页面很慢。react为了避免这类DOM事件的滥用

有哪些场景下需要使用原生 DOM 事件?​

一般情况下,React 的合成事件已经能满足大部分需求了,有时候也需要使用原生事件

  • 需要监听React组件之外的DOM节点,比如window和document对象的事件

在组件监听DOM事件,是有副作用的,需要在清除函数中取消监听

js
useEffect(() => {
window.addEventListener('resize', handleResize);
return function cleanup() {
window.removeEventListener('resize', handleResize);
};
}, []);

React事件和原生事件的执行顺序​

React在合成事件上对于 16版本和 17版本的合成事件有很大不同

  • 16版本先执行原生事件,当冒泡到 document时,统一执行合成事件,
  • 17版本在原生事件执行前先执行合成事件捕获阶段,原生事件执行完毕执行冒泡阶段的合成事件,通过根节点来管理所有的事件