事件委托和事件池

a39a1978ecd13529d506ba2b2497fa82.png

React 的合成事件是通过事件委托(event delegation)和事件池(event pooling)的机制来实现的。下面是合成事件的简单原理介绍:

1、 事件委托:React 使用事件委托将事件处理函数附加到父元素上,而不是直接将事件处理函数附加到每个子元素上。这意味着只需要一个事件监听器来处理整个组件树中的所有事件。当事件发生时,事件会冒泡到父元素,然后由 React 在父元素上触发相应的事件处理函数。

2、 事件池:React 使用事件池来重用事件对象,以减少内存分配和垃圾回收的开销。当事件发生时,React 会从事件池中获取一个事件对象,并将相关的信息(如事件类型、目标元素等)填充到事件对象中。然后,事件对象会被传递给事件处理函数。在事件处理完成后,React 会将事件对象重置,并放回事件池中,以便下次重用。

合成事件的原理带来了一些优势:

1、 跨浏览器兼容性:React 的合成事件封装了底层浏览器差异,使得事件在不同浏览器中表现一致,无需开发者自己处理兼容性问题。

2、 性能优化:通过事件委托,React 可以减少事件监听器的数量,从而提高性能。而且,事件池的机制可以减少内存分配和垃圾回收的开销,提升整体性能。

3、 事件代理:事件委托使得 React 可以在父组件上捕获事件,并根据事件的目标元素来触发相应的事件处理函数。这样可以更灵活地处理事件,而不需要为每个子元素都添加事件监听器。

4、 合成事件属性:React 的合成事件对象提供了一些额外的属性,例如 event.targetevent.currentTargetevent.preventDefault() 等,方便开发者对事件进行处理和控制。

总结起来,React 的合成事件通过事件委托和事件池的机制,提供了跨浏览器兼容性、性能优化、事件代理和额外的事件属性等优势,使得事件处理更加方便和高效。

事件池

合成事件 SyntheticEvent 对象会被放入池中统一管理。这意味着 SyntheticEvent 对象可以被复用,当所有事件处理函数被调用之后,其所有属性都会被置空。

例如,以下代码是无效的:

function handleChange(e) {
  // This won't work because the event object gets reused.
  setTimeout(() => {
    console.log(e.target.value); // Too late!
  }, 100);
}

如果你需要在事件处理函数运行之后获取事件对象的属性,你需要调用 e.persist():

function handleChange(e) {
  // Prevents React from resetting its properties:
  e.persist();


  setTimeout(() => {
    console.log(e.target.value); // Works
  }, 100);
}

以下是一个简单的代码演示,展示如何使用事件池:

var eventPool = {
  events: [],


  getEvent: function(eventType) {
    if (this.events.length > 0) {
      return this.events.pop();
    } else {
      return { type: eventType };
    }
  },


  releaseEvent: function(event) {
    event.target = null;
    event.currentTarget = null;
    this.events.push(event);
  }
};


// 使用事件池对象获取和释放事件
var eventType = 'click';
var event = eventPool.getEvent(eventType);


// 模拟事件处理
console.log('处理事件:', event);


// 释放事件到事件池
eventPool.releaseEvent(event);

实际上,React 17 不再使用事件池的概念。React 17 引入了一个新的事件系统,称为"无池事件系统"(No Pooling Event System)。

在之前的 React 版本中,事件池的目的是为了重用事件对象,以减少内存分配和垃圾回收的开销。然而,随着现代浏览器的发展和性能改进,以及对 React 内部事件系统的优化,事件池的性能优势逐渐减弱。

React 17 的无池事件系统采用了一种新的事件处理机制,它不再重用事件对象,而是在每次事件触发时创建一个新的事件对象。这样做的主要原因是,现代浏览器在处理大量短暂的事件对象时,已经具备了很好的性能优化能力,不再需要手动管理事件对象的重用。

<button id="myButton">点击我</button>


<script>
  function simulateSyntheticEvent(element, eventType) {
    var event = new CustomEvent(eventType, {
      bubbles: true,
      cancelable: true,
    });
    element.dispatchEvent(event);
  }


  function handleClick(event) {
    console.log('点击事件触发');
  }


  var button = document.getElementById('myButton');
  button.addEventListener('click', handleClick);


  // 模拟点击事件
  simulateSyntheticEvent(button, 'click');
</script>

通过移除事件池,React 17 在事件处理方面获得了一些优势:

1、 更好的跨浏览器兼容性:不再需要担心不同浏览器对事件池的支持和行为差异。

2、 更简化的代码逻辑:无需关注事件对象的释放和重用,减少了开发者需要处理的细节。

3、 更好的可维护性和可扩展性:去除事件池使 React 内部的事件系统更加简洁和灵活,有助于未来的优化和改进。

需要注意的是,尽管 React 17 不再使用事件池,但它仍然提供了一套强大的合成事件机制,使开发者可以方便地处理和管理事件。你可以像之前一样,在 React 组件中定义事件处理函数,并将其传递给相应的事件属性,React 将负责处理事件的创建和传递。

综上所述,React 17 不再使用事件池的原因是为了简化代码逻辑、提供更好的跨浏览器兼容性,并利用现代浏览器的性能优化能力。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
React事件委托是指在React中,通过将事件监听器添加到父组件上,从而实现对子组件的事件处理。React使用事件委托的方式来提高性能和代码复用。通过事件委托,可以在父组件上监听特定类型的事件,并在合适的时候将事件传递给对应的子组件进行处理。 在React中,事件委托的实现主要依靠React事件系统和组件的虚拟DOM机制。React使用了一种称为合成事件(SyntheticEvent)的机制来处理事件。当父组件监听到一个特定类型的事件时,React会将这个事件转化为一个合成事件对象,并将这个对象传递给父组件的事件处理函数。然后父组件可以根据合成事件对象的信息,判断事件源是哪个子组件,并调用相应的子组件的事件处理函数进行处理。 引用和是关于React事件委托的源码文件。其中,ReactBrowserEventEmitter.js定义了React事件委托的核心逻辑,包括事件的注册、分发等功能。而引用的ReactDOMEventListener.js则负责将DOM事件转化为合成事件。 综上所述,React事件委托是通过将事件监听器添加到父组件上,利用React事件系统和虚拟DOM机制,实现对子组件的事件处理和分发。这种机制可以提高性能和代码复用,并且方便管理事件逻辑。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [jquery 监听td点击事件_React 事件 | 1. React 中的事件委托](https://blog.csdn.net/weixin_39538789/article/details/110105355)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值