React方法绑定的几种实现方式
翻译参考自:React and ES6 - Part 3, Binding to methods of React class (ES7 included)
在React进行事件方法绑定的时,如下面的代码:
import React , {Component} from 'react'
class user extends Component{ render(){ return <button onClick={this.sayhello} >open hello</button> }
sayhello(){ console.log('hello world') console.log(this.props) }}
export default user我们将会得到“TypeError: Cannot read property ‘props’ of null“的错误,如下图所示:

这是因为当我们调用以这种方式绑定到this的方法时,没有将函数上下文绑定到组件的实例上。这是Javascript的默认行为而且是可以明确预期到的。
React团队在实现支持ES6时不支持自动绑定,你在这篇博客中找到更多关于这样做的原因。
下面将介绍几种不同的方式实现,在JSX中使用ES6语法调用class method。
方法一、 使用Function.prototype.bind()
Section titled “方法一、 使用Function.prototype.bind()”如下面的代码:
// 使用bind()class user extends Component{ render(){ return <button onClick={this.sayHello.bind(this)} >open hello</button> }
sayHello(){ console.log(this.props) }}任何ES6类的方法都是纯JavaScript函数,并从Function prototype继承了bind()方法,所以当我们调用sayHello方法时,this将会指向我们的组件实例。在MDN article可以找到更多的相关信息。
方法二、 使用在constructor中定义的方法
Section titled “方法二、 使用在constructor中定义的方法”// 使用构造函数定义的方法class user1 extends Component{ constructor(props){ super(props) this._sayHello = ()=> this.sayHello(); }
sayHello(){ console.log(this.props) }
render(){ return (<button onClick={this.sayHello}>open hello 1</button>) }}这种方式中,不再需要在JSX中使用bind(),但会使构造函数更加膨胀。
方法三、使用箭头操函数和构造函数
Section titled “方法三、使用箭头操函数和构造函数”ES6箭头函数会保留定义时的this上下文,即当调用箭头函数时,函数体内的this对象,就是定义时所在的对象,而不是调用时所在的对象。所以可以利用这个特性,并在构造函数中重新定义sayHello方法。
// 箭头函数 + 构造函数class user extends Component{ constructor(props){ super(props) this._sayHello = ()=> this._sayHello() }
sayHello(){ console.log(this.props) }
render(){ return <button onClick={this._sayHello.bind(this)} >open hello3</button> }}方法四、使用箭头函数和ES6类属性
Section titled “方法四、使用箭头函数和ES6类属性”可以通过使用箭头函数和ES6类属性语法:
// 箭头函数 + ES属性语法class user extends Component{ sayHello = ()=>{ console.log(this.props) }
render(){ return <button onClick={this.sayHello} >open hello4</button> }}上面出现的代码下在地址: github