// React官方文档中的代码
class Toggle extends React.Component {
constructor(props) {
super(props);
this.state = {isToggleOn: true};
// 为了在回调中使用 `this`,这个绑定是必不可少的
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
this.setState(state => ({
isToggleOn: !state.isToggleOn
}));
}
render() {
return (
<button onClick={this.handleClick}>
{this.state.isToggleOn ? 'ON' : 'OFF'}
</button>
);
}
}
ReactDOM.render(
<Toggle />,
document.getElementById('root')
);
handleClick
函数需要在constructor中绑定this
// 为了在回调中使用 `this`,这个绑定是必不可少的
this.handleClick = this.handleClick.bind(this);
理解:
1、 在class中,构造函数中定义的数据是直接属于实例对象的,在类里定义的函数是属于类的原型的,实例对象调用时,原型函数才存在this对象
2、 在<button onClick={this.handleClick}>
这段代码中是把handleClick
函数直接赋值给了onClick
函数,所以事件触发时直接相当于直接调用的onClick
函数,因此没有this
所以有一种修改方式如下,用一个箭头函数包裹执行handleClick
函数,这样就能拿到正确的this了
class LoggingButton extends React.Component {
handleClick() {
console.log('this is:', this);
}
render() {
// 此语法确保 `handleClick` 内的 `this` 已被绑定。
return (
<button onClick={() => this.handleClick()}>
Click me
</button>
);
}
}
缺陷:此语法问题在于每次渲染 LoggingButton 时都会创建不同的回调函数。在大多数情况下,这没什么问题,但如果该回调函数作为 prop 传入子组件时,这些组件可能会进行额外的重新渲染。–官方文档解释
此外,还有一种解决方式,使用箭头函数定义handleClick
函数(箭头函数被绑定在构造函数上,相当于实例对象,性能也较差,每个实例对象都存在一个箭头函数)
class LoggingButton extends React.Component {
// 此语法确保 `handleClick` 内的 `this` 已被绑定。
// 注意: 这是 *实验性* 语法。
handleClick = () => {
console.log('this is:', this);
}
render() {
return (
<button onClick={this.handleClick}>
Click me
</button>
);
}
}