问题
为什么React需要用bind重新指向?
this指向
问题一直都是很令人头疼的问题,而在React
中常常用this.handleClick = this.handleClick.bind(this)
重新指向所在类,在这里记录一下自己的理解。
this指向
在解决问题之前,我们先要记住两句话,
普通函数中this的指向,是this执行时的上下文
箭头函数中this的指向,是this定义时的上下文
普通函数例子
var name = 'lili',age = 15;
var obj={
name : 'Bob',
objage : this.age,
fun : function(){
console.log(this.name+''+this.age);
}
};
console.log(obj.objage);
obj.fun();
我想上面这个例子大家都不陌生吧,刚接触js的时候,一定搞了很久才搞明白,我们还是先从这个例子入手。
var
只是定义了变量,不会自己去调用,我们调用obj.objage,obj是一个对象,obj.objage
就等于this.age
,那这个this指代什么,我们刚刚说了普通函数中this是执行时的上下文,这个obj在哪里执行的?在整个js代码即全局中执行的,所以this.age=15
。
调用obj.fun()
,fun函数所执行的上下文就是obj这个对象,所以this就指代obj这个对象,this.name=bob
,但obj中没有age这个属性,所以是undefined
。
bind
箭头函数
class Example extends React.Component{//定义一个组件类Example
handleClick = () => {//定义一个箭头函数
console.log(this);
}
render(){
return (
<div>
<button onClick={this.handleClick}>click</button>
</div>
);
}
}
ReactDOM.render(
<Example />,
document.querySelector("div")
);
发现他打印的是Example
这个类,箭头函数是this定义时的上下文。当我们点击按钮,会调用handleClick
方法来处理事件,handleClick是在Example类中定义的,所以this指代Example
这个类。
普通函数
class Example extends React.Component{//定义一个组件类Example
handleClick(){//定义一个普通函数
console.log(this);
}
render(){
return (
<div>
<button onClick={this.handleClick}>click</button>
</div>
);
}
}
ReactDOM.render(
<Example />,
document.querySelector("div")
);
我们发现是undefined,普通函数是this执行时的上下文,点击按钮,调用handleClick来处理事件,this.handleClick中的this指向的还是这个类,因为render首先只是渲染虚假的dom树
,但当真正插入节点后,我们点击按钮,执行环境以及变成了HTML页面,this这时已经指向了button组件,所以找不到相应的函数。
普通函数+bind
<button onClick={this.handleClick.bind(this)}>click</button>
在原来基础上,bind
函数是创建一个新函数,称为绑定函数,将调用绑定函数的函数绑定到bind的第一个参数上。再渲染虚假dom树时,this指向Example这个类,相当于Example.handleClick.bind(Example)
,把handleClick这个函数绑定到Example类,使得this始终指向Example。