React 的合成事件与 addEventListener 相比有什么优势吗?

IT技术 reactjs
2021-05-21 08:05:47

我有一个管理 HTML 音频元素的 React 组件。AFAIU 有两种方法可以实现这一点:将音频元素作为属性放在类实例上,或者将其放在render()方法中并ref在其上粘贴 a

因为第二个选项不直接创建音频元素,而是通过 React.createElement,我可以使用 Reacts 合成事件系统 - 而第一个选项需要使用 addEventListener 添加事件侦听器。我的问题是,第二种选择是否有任何优势?

(选项1)

class A extends React.Component {
  audio = new Audio();
  componentDidMount() {
    this.audio.addEventListener('play', () => console.log('Started playing'));
  }
  play() {
    this.audio.play();
  }
  render() {
    return (
      <div>
        <button onClick={this.play}>Play</button>
      </div>
    );
  }
}

(选项 2)

class A extends React.Component {
  play() {
    this.audio.play();
  }
  render() {
    return (
      <div>
        <audio
          ref={audio => this.audio = audio}
          onPlay={() => console.log('Started playing')}
        />
        <button onClick={this.play}>Play</button>
      </div>
    );
  }
}
2个回答

合成事件只是普通事件的包装器。它们在浏览器不一致和大量事件之间提供通用接口,最终由于事件池而性能更好

您正在通过e.nativeEvent访问原始事件

合成事件在某种意义上更好,因为它们更易于使用(更少的代码,在所有浏览器之间都没有麻烦地支持)并且它们更可靠,因为 React 在呈现的元素之后添加它们并且在 DOM 中可用。componentDidMount被调用时,您无法确定该元素是否实际存在于浏览器 DOM 中。componentDidMount当 React 告诉浏览器将元素附加到 DOM 并在它自己的虚拟 DOM 中计算出必要的内容时调用。但是如果渲染线程以任何方式忙碌,浏览器可能不会渲染元素。