React 事件绑定/this绑定的几种方式
MDN中 Function.prototype.bind()
bind() 方法创建一个新的函数,在 bind() 被调用时,这个新函数的 this 被指定为 bind() 的第一个参数,而其余参数将作 为新函数的参数,供调用时使用。
先引入一个例子:
const module = {
  x: 42,
  getX: function() {
    return this.x;
  }
};
let unboundGetX = module.getX;
console.log(unboundGetX()); // 该函数在全局范围内被  调用
// 输出: undefined
unboundGetX = unboundGetX.bind(module);
console.log(unboundGetX());
// 输出: 42
一个 module 对象中包含一个变量x和一个方法getX。将 module 中的getX方法赋值给一个外面声明的变量 unboundGetX ,此时 unboundGetX 仅仅和getX有关系,unboundGetX中的this指向 undefined ,输出 unboundGetX() 为undefined。
后面使用bind()方法将unboundGetX中的this指向了 module ,作为新函数返回并赋值给unboundGetX,此时unboundGetX中的this就指向了 module 。最后输出 unboundGetX() 的结果为 42 .
一般在哪里调用,它的this就指向哪里。在对象、class等花括号外的,严格模式下this为undefined,非严格模式指向window对象。
在这个例子告诉我们,绑定this的重要性,接下来看看常见的绑定this的方式,以免绑定事件报错 undefined。
为事件方法绑定this的四种常见方式
①【推荐】在constructor中绑定:
class App extends React.Component{
  x='Its me.'
 
  constructor(props){
    super(props);
    this.Log = this.Log.bind(this)// 在constructor中绑定this
  }
  
  Log() {
    console.log(this.x)
  }
  
  render() {
    return (
      <button onClick={this.Log}></button>// 事件绑定
    );
  }
}
②【推荐】class fields实验性语法,定义时使用箭头函数:
class App extends React.Component{
  x='Its me.'
 
  constructor(props){
    super(props);
  }
  
  Log = ()=>{ // 使用箭头函数来定义函数
    console.log(this.x)
  }
  
  render() {
    return (
      <button onClick={this.Log}></button> // 事件绑定
    );
  }
}
③【不建议】在render中绑定事件时使用bind()绑定this:
class App extends React.Component{
  x='Its me.'
 
  constructor(props){
    super(props);
  }
  
  Log() {
    console.log(this.x)
  }
  
  render() {
    return (
      <button onClick={this.Log.bind(this)}></button> // 事件绑定
    );
  }
}
④【不建议】在render中绑定事件时使用箭头函数 ( )=>{ } 绑定this:
class App extends React.Component{
  x='Its me.'
 
  constructor(props){
    super(props);
  }
  
  Log() {
    console.log(this.x)
  }
  
  render() {
    return (
      <button onClick={ ()=>{this.Log()} }></button> // 事件绑定
    );
  }
}
onClick = {this.Log} ,实际上onClick是个变量,若不将this绑定到对象,将对象中的Log赋值给了onClick,此时触发点击事件时,onClick中的this为undefined(class中为严格模式),出错。所以函数中如果使用了this,一定要将this绑定到对象,否则在事件绑定时会丢失函数中this的指向。
以上是常见的四种方法,通常建议在constructor中绑定或使用 class fields 语法来避免性能问题。在render中每次渲染都会绑定一次,有可能影响性能
