从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。