事件处理

我们需要在constructor中对于事件与对应的handler函数进行绑定.

大多数时候我们在发出DOM事件的组件内部写我们的handler函数. 在下面的例子中,我们在组件内部创建了一个click handler, 因为我们想所有的Swithcer Component当被点击时,做出同样的响应.

class Switcher extends React.Component {
  render() {
    return (
      <button onClick={ this._handleButtonClick }>
        click me
      </button>
    );
  }
  _handleButtonClick() {
    console.log('Button is clicked');
  }
}

上面这样做完全没有问题,因为_handleButtonClick是一个函数, 我们把这个函数和onClick这个React支持的event绑定在了一起.

但是上面这样做也会带来问题, 使用function的写法, 会在function初始化时生成一个this. 比如我们在_handleButtonClick里面使用this, 此时的this是_handleButtonClick生成出来的, 和Switcher这个class的this没有任何关系, 如果我想访问类似于this.props 或者 this.state这样的对象, 代码便会报错.

class Switcher extends React.Component {
  constructor(props) {
    super(props);
    this.state = { name: 'React in patterns' };
  }
  render() {
    return (
      <button onClick={ this._handleButtonClick }>
        click me
      </button>
    );
  }

  _handleButtonClick() {
    console.log(`Button is clicked inside ${ this.state.name }`);
    // 将导致
    // Uncaught TypeError: Cannot read property 'state' of null
  }
}

所以我们常用的解决办法像下面一样使用bind

<button onClick={ this._handleButtonClick.bind(this) }>
  click me
</button>

然而, 这种写法意味这我们要一次又一次的去调bind函数, 因为我们的button可能会被渲染很多次. 一种更好的做法是在组件的constructor中去做我们bind函数的调用.

class Switcher extends React.Component {
  constructor(props) {
    super(props);
    this.state = { name: 'React in patterns' };
    this._buttonClick = this._handleButtonClick.bind(this);
  }
  render() {
    return (
      <button onClick={ this._buttonClick }>
        click me
      </button>
    );
  }
  _handleButtonClick() {
    console.log(`Button is clicked inside ${ this.state.name }`);
  }
}

另一种办法是使用箭头函数建立我们的handler函数, 因为箭头函数并不会创建this.

顺带一提的是, Facebook也推荐使用这种方法去处理需要访问组件的this的函数.

但是, 在constructor中去做binding也同样有用处. 比如, 我们可能会将父组件中定义的函数作为Props传下去. 因此在子组件中, 我们需要对这个函数进行bind.

results matching ""

    No results matching ""