React ES6类组件方法的绑定

从React 0.13.0就开始支持使用ES6类来新建React组件,方法遵循与普通ES6的class中相同的语义。也就是说方法不会自动绑定this到实例中,你必须在构造函数中显式的使用.bind(this)。

看下面代码:

class Greeting extends React.Component {
  constructor(props) {
    super(props);
    this.state = {message: 'Hello!'};
    // 这一行很重要!
    this.sayHello= this.sayHello.bind(this);
  }

  sayHello() {
    alert(this.state.message);
  }

  render() {
    // 因为 `this.sayHello` 是绑定的,所以我们可以使用它作为一个事件处理程序。
    return (
      <button onClick={this.sayHello}>
        Say hello
      </button>
    );
  }
}

在createReactClass()中,并不需要这么做,因为方法可以自动绑定。

class Greeting extends React.Component {
  constructor(props) {
    super(props);
    this.state = {message: 'Hello!'};
  }
  // 警告:这个语法是实验性的!
  // 这里使用箭头绑定方法:
  sayHello = () => {
    alert(this.state.message);
  }

  render() {
    return (
      <button onClick={this.sayHello}>
        Say hello
      </button>
    );
  }
}

或者更早版本(16.0.0以前)用法var Greeting = React.createReactClass({…})。这意味着使用ES6类组件方式,对于事件处理函数需要编写更多的代码 ,但是这种方式在大型应用中具有更好的性能。

如果你不想使用样本代码,你可以使用 Babel 启用 实验性的类属性语法提案:

class Greeting extends React.Component {
  constructor(props) {
    super(props);
    this.state = {message: 'Hello!'};
  }
  // 警告:这个语法是实验性的!
  // 这里使用箭头绑定方法:
  sayHello = () => {
    alert(this.state.message);
  }

  render() {
    return (
      <button onClick={this.sayHello}>
        Say hello
      </button>
    );
  }
}

请注意,上述语法是实验性的,并且这个语法将来可能会发生变化,或者这个提案可能不会纳入语言范畴。

如果你想更稳妥的方法,你有以下选择:

  • 在构造函数中绑定方法。
  • 使用箭头函数,例如,onClick={(e) => this.sayHello(e)}
  • 保持使用 createReactClass或者React.createReactClass。

注意ES6中函箭头数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。this指向的固定化,并不是因为箭头函数内部有绑定this的机制,实际原因是箭头函数根本没有自己的this,导致内部的this就是外层代码块的this。

发表评论

电子邮件地址不会被公开。 必填项已用*标注