欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 汽车 > 新车 > react18中的合成事件与浏览器中的原生事件

react18中的合成事件与浏览器中的原生事件

2024/10/27 11:28:29 来源:https://blog.csdn.net/qq_27702739/article/details/143184056  浏览:    关键词:react18中的合成事件与浏览器中的原生事件

React 通过将事件 normalize 以让他们在不同浏览器中拥有一致的属性。

  • 合成事件

    SyntheticEvent 实例将被传递给你的事件处理函数,它是浏览器的原生事件的跨浏览器包装器。除兼容所有浏览器外,它还拥有和浏览器原生事件相同的接口,包括 stopPropagation() 和 preventDefault()。

    如果因为某些原因,当你需要使用浏览器的底层事件时,只需要使用 nativeEvent 属性来获取即可。合成事件与浏览器的原生事件不同,也不会直接映射到原生事件。例如,在 onMouseLeave 事件中 event.nativeEvent 将指向 mouseout 事件。每个 SyntheticEvent 对象都包含以下属性:

    boolean bubbles
    boolean cancelable
    DOMEventTarget currentTarget
    boolean defaultPrevented
    number eventPhase
    boolean isTrusted
    DOMEvent nativeEvent
    void preventDefault()
    boolean isDefaultPrevented()
    void stopPropagation()
    boolean isPropagationStopped()
    void persist()
    DOMEventTarget target
    number timeStamp
    string type
    
import { Component } from "react";
class ClassComp extends Component {state = {count: 10,};handleAdd = (e) => {this.setState({ count: this.state.count + 1 });console.log(e);};render() {const { count } = this.state;return (<div>Class Component<p>{count}<br /><button onClick={this.handleAdd}>add</button></p></div>);}
}
export default ClassComp;

SyntheticBaseEvent是对浏览器原生事件的一个封装,让不同的浏览器的 API 表现一致。浏览器常用的事件基本都有
在这里插入图片描述

  • 原生事件
<body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><div id="box"><button id="btn">提交</button></div><script>window.onload = function () {const btn = document.getElementById("btn");btn.onclick = handleClick;};function handleClick(e) {console.log("🚀 ~ handleClick ~ e:", e);console.log("提交成功");}</script>
</body>

在这里插入图片描述

  • 是要方法经过 bind 处理,那么最后一个实参就是传递的合成事件对象。
handleAdd = (x, e) => {console.log("🚀 ~ ClassComp ~ x:", x);console.log(e);
};
<button onClick={this.handleAdd.bind(null, 20)}>add</button>;
  • 直接使用箭头函数,获取事件对象和参数
handleAdd2 = (e, x) => {console.log("🚀 ~ ClassComp ~ e, x:", e, x);
};
<button onClick={(e) => this.handleAdd2("10", e)}>add2</button>;

事件委托

利用事件的传播机制,将事件绑定到父元素上,通过判断目标元素来执行相应的事件。
传统方法是直接获取元素,然后绑定事件。

  • 事件的捕获和冒泡

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

  • 目标元素阻止冒泡

  • event.stopPropagation()在事件对象中,调用该方法将阻止事件(包括冒泡或捕获)在 DOM 中继续传播。

  • event.stopImmediatePropagation()在事件对象中,调用该方法其他未执行的方法也不会执行了
    在这里插入图片描述
    在这里插入图片描述

  • 最外层阻止冒泡,阻止事件继续向上传播
    在这里插入图片描述
    在这里插入图片描述

React 中合成事件的原理

  • 合成事件绝对不是直接给元素addEventListener进行事件的绑定,而是通过事件委托的方式,给 document 进行事件的绑定。
  • r17 之前的 React 内部通过事件池SyntheticEvent来统一处理浏览器兼容问题,并且将事件委托给 document,且只做了对冒泡阶段的委托。
  • 事件池SyntheticEvent是一个对象,用来包装原生事件。
  • r17 及以后版本,事件池SyntheticEvent是单例模式。都是委托给#root 这个容器,捕获和冒泡都做了委托
  • 事件池SyntheticEvent对象在事件池中缓存,当事件触发时,会从事件池中获取一个对象。
  • 对于没有事件传播机制的事件,才是单独做的事件绑定。例如,onMouseEnter,onMouseLeave,onFocus 等。
  • 在组件渲染的时候,如果发现有 onXxx,onXxxxCapture 这样的属性,不会直接给元素绑定事件,只是把该方法作为属性保存到组件的实例上。然后对#root 容易做了事件绑定。
    在这里插入图片描述
    在这里插入图片描述

React中合成事件的处理原理

在16版本中,合成事件的处理机制,不再是把事件委托给#root元素,而是委托给docunent元素,并且只做了冒泡阶段的委托:在委托的方法中,把onXxx/onMxxcaptare合成事件属性进行执行!
React16中,关于含成事件对象的处理,react内部是基于”事件对象池”做了一个缓存机制!react17及以后,是去掉了这套事件对象池和缓存机制的!

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com