react中事件处理时为什么要手动绑定this?

543 阅读1分钟

react中事件处理时为什么要手动绑定this?

首先我们都知道this是谁来调用就指向谁,那为什么react中事件处理的时候要手动绑定this,难道它不是由组件实例调用的?恭喜你,你答对了,事件处理函数确实不是由组件实例来调用的。

class组件必须要有一个render函数,里面返回一个react元素。

render()方法类似于下面这样

render(){
    return (<a href="#" onClick={this.handleClick}>click me </a>
})

他的本质是React.createElement(component, props, ...children) 的语法糖,他最终会被解析成下面这样的代码

render(){
   return React.createElement(
    "a", 
    { onClick: this.handleClick}, 
    "click me"
    );
   }

可以看到this.handleClick被当做一个参数传递给了React.createElement方法,这个时候当我们在外部触发click事件的时候它的this就丢失了

举个例子来解释下,

看下面这个代码

class Point {
  constructor(x, y) {
        this.x = x;
        this.y = y;
        //this.toString = this.toString.bind(this) //先注释掉
  }

  toString() {
        console.log('(' + this.x + ', ' + this.y + ')');
  }
  render(){
        return {
                click:this.toString
        }
  }
}
let pointa = new Point(1,2)
pointa.toString()      //打印 (1, 2)
let reactEle = pointa.render()
reactEle.click()      //打印 (undefined, undefined)

可以看到当我们把toString方法作为参赛传出,再去调用的时候,他的this已经丢失了

取消this.toString = this.toString.bind(this)的注释

class Point {
  constructor(x, y) {
        this.x = x;
        this.y = y;
        this.toString = this.toString.bind(this)
  }

  toString() {
        console.log('(' + this.x + ', ' + this.y + ')');
  }
  render(){
        return {
                click:this.toString
        }
  }
}
let pointa = new Point(1,2)
pointa.toString()     //打印 (1, 2)
let reactEle = pointa.render()
reactEle.click()      //打印 (1, 2)

ok,这下不管怎么样都是绑定到实例的this