关于react事件机制: SyntheticEvent 什么情况下对象可能会被重用

发布于 2022-09-11 21:22:19 字数 296 浏览 36 评论 0

react 官网关于事件池的描述如下
SyntheticEvent 是合并而来。这意味着 SyntheticEvent 对象可能会被重用,而且在事件回调函数被调用后,所有的属性都会无效。出于性能考虑,你不能通过异步访问事件。

SyntheticEvent 对象可能会被重用,有没有大神帮忙说明下什么情况下回出现对象重用

另外,有点不明白这个重用,是什么意思

clipboard.png

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

水晶透心 2022-09-18 21:22:19

挺好的问题。

先说一个SyntheticEvent的背景吧。React 使用 SyntheticEvent 主要有两个目的:

  • 抹平不同浏览器事件对象之间的差异(tricks)
  • 避免垃圾回收。事件对象可能会被频繁创建和回收,所以React搞了一个‘事件池’,从这个池中获取或释放事件对象。简单说,事件对象压根不会被释放掉,而放进一个数组中,一有事件触发,就从这个数组中弹出来,这样就避免频繁地去创建和销毁(垃圾回收)

具体实现见SyntheticEvent

那什么时候会被回收呢?

要研究它怎么被调用的最佳方式是给你的事件处理器打一个断点,例如:

图片描述

你可以一个一个点开瞧瞧:

function runExtractedEventsInBatch(topLevelType, targetInst, nativeEvent, nativeEventTarget) {
  var events = extractEvents(topLevelType, targetInst, nativeEvent, nativeEventTarget); // ? 在这里创建一个SyntheticEvent
  runEventsInBatch(events);
}

再往下瞧瞧:

var executeDispatchesAndRelease = function (event) {
  if (event) {
    executeDispatchesInOrder(event); // ? 按冒泡的顺序执行事件处理器,这是同步执行的

    if (!event.isPersistent()) {
      event.constructor.release(event); // ? 释放SyntheticEvent对象
    }
  }
};

Ok,我想我应该讲明白了,关于事件这一块,React内部的实现还是很复杂的,有机会再写写文章说一下。

最后, 如果你想在异步场景或者想持久地引用SyntheticEvent对象,建议以下两种方式:

  • 调用SyntheticEvent#persist()方法, 告诉React不要释放。 如上面的代码所示:!event.isPersistent()判断是否是‘持久’的,是就不会释放掉
  • 直接引用SyntheticEvent#nativeEvent。 推荐这种方式

欢迎关注我,和我交流

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文