1、为什么React中Class component组件中this需要进行bind()
React官网上基本概念之事件处理里明确指出:This is not React-specific behavior; it is a part of how functions work in javascript(这是由于js函数的运行机制所决定的).但是,这仍会使很多刚接触React的开发者感到困惑。其实,如果需要理解这句话,那么首先需要理解ES6 class的部分特征与复杂类型的引用赋值。
(1)class里定义的方法是定义在实例对象的原型对象(prototype)上的;
(2)class里块级作用于里的代码,默认是strict模式的;
(3)对于const fun1 = object.fun2; 这句话,仅仅是将object里属性名为fun2的函数的堆地址赋值给fun1,后面fun1如何调用,与object一点关系都没有;
如果理解了以上三点,在结合下面代码的 1)-> 2) -> 3), 那就一目了然了。
class Toggle extends React.Component {
constructor(props) {
super(props);
this.state = {isToggleOn: true};
// (1) This binding is necessary to make `this` work in the callback
// 右侧this.handleClick为实例调用prototype上的方法,然后绑定this为实例自己
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
// (3) 即未bind下,this.setState中this = undefined
this.setState(state => ({
isToggleOn: !state.isToggleOn
}));
}
render() {
return (
/* (2) 对于onClick = this.handleClick,仅仅是函数赋值 在浏览器环境下onClick引用的函数被调用,
这个函数里面的this若不绑定元素自身,则strict模式下为undefined,而class内代码为默认严格模式 */
<button onClick={ this.handleClick }>
{ this.state.isToggleOn ? 'ON' : 'OFF' }
</button>
);
}
}
ReactDOM.render(
<Toggle />,
document.getElementById('root')
);
2)对于使用箭头函数的方式,那就需要理解另外一点:
(4)箭头函数自身没有this绑定,其函数体里的this取决于词法作用于;对于在class里定义的箭头函数,其函数体里的this等于class里的this,即指向实例对象。理解了这句话,那么不论是使用 handleClick = () {},还是onClick={() => this.handleClick}其本质都是箭头函数的this取决于词法作用域。
(1) public class fields syntax
class LoggingButton extends React.Component {
// This syntax ensures `this` is bound within handleClick.
// Warning: this is *experimental* syntax.
handleClick = () => {
// class环境中定义的箭头函数里的this指向实例
console.log('this is:', this);
}
render() {
return (
<button onClick={ this.handleClick }>
Click me
</button>
);
}
}
(2) 箭头函数里返回一个函数
class LoggingButton extends React.Component {
handleClick() {
console.log('this is:', this);
}
render() {
// This syntax ensures `this` is bound within handleClick
return (
// 本质是箭头函数中this属于词法作用于,在编译时就已经确定
<button onClick={() => this.handleClick()}>
Click me
</button>
);
}
}