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了