Native和ReactJS事件的排序

时间:2015-07-10 16:54:37

标签: events reactjs dom-events

所以我有这个例子来展示我正在使用的一些代码我遇到的问题(由于多种原因无法发布确切的代码)。

http://codepen.io/anon/pen/jPxzar

var Test1 = React.createClass({
  getInitialState: function() {
    return {
      events: ['Demo loaded'],
      buttonClicked: false
    };
  },

  componentWillMount: function() {
    document.addEventListener('click', this.onDocumentClick);
  },

  onDocumentClick: function() {
    var message = 'on document click event (button clicked: ' + this.state.buttonClicked + ')';
    this.setState({
      events: this.state.events.concat([message]),
      buttonClicked: false
    });
  },

  onButtonClick: function() {
    this.setState({
      events: this.state.events.concat(['on button click event']),
      buttonClicked: true
    });
  },

  render: function() {
    return (
      <span>
        <button onClick={this.onButtonClick}>Button</button>
        <div>Events:</div>
        <ul>
          {this.state.events.map(function(message) {
            return <li>{message}</li>;
          })}
        </ul>
      </span>
    );
  }
});

React.render(
  <Test1 />, 
  document.getElementById('mount-point'));

这里我有一个组件在安装时在文档上添加了一个本机点击事件处理程序,因为我需要跟踪页面上任何地方发生的任何点击,而不仅仅是在这个组件中。我还有一个具有ReactJS事件处理程序的按钮。如果我点击按钮外的任何地方,一切正常。如果我单击该按钮,则会触发这两个事件,但首先触发本机事件,然后触发React事件,但我需要首先触发React事件。

如何确保在React事件之后始终执行本机附加事件?

2 个答案:

答案 0 :(得分:0)

事件似乎是按照添加侦听器的顺序触发的。我做了一些挖掘,并在DOM3 spec中发现了一些似乎支持这一点的信息,但我还不太确定预期的行为应该是什么。

无论如何,我测试了我的理论,它似乎产生了预期的效果:http://codepen.io/anon/pen/EjLRbK

总结一下:您目前正在componentWillMount中创建本机事件监听器。此函数在组件对render的初始调用之前执行,因此首先创建本机事件侦听器。如果将其更改为componentDidMount,则会在初始调用render后执行,并且将首先创建render中的事件侦听器,并在单击按钮时首先调用该事件侦听器你的示例代码。

答案 1 :(得分:0)

根据我的调试经验,在呈现实际组件树之前,已经在“根”元素上注册了两个单击事件处理程序。因此,“root”元素上的任何 dom 事件侦听器都是从索引 2 添加的。因此,总是先触发 react 事件,然后再触发“root”元素上的 dom 事件。