为何无法将() => {...}替换为function() {...}?React setState报错问题
为什么箭头函数换成普通function后setInterval里的setState会报错?
这是个非常典型的this绑定问题,咱们来拆解清楚:
先看你的两段代码
- 可正常运行的箭头函数版本:
// 每隔一秒切换状态 setInterval( () => { this.setState(previousState => { return { isShowingText: !previousState.isShowingText }; }); }, 1000);
- 无法运行的普通function版本:
// 每隔一秒切换状态 setInterval( function() { this.setState(previousState => { return { isShowingText: !previousState.isShowingText }; }); }, 1000);
核心原因:this的绑定规则不一样
箭头函数的
this是词法绑定:它不会自己创建this,而是直接继承外层作用域(也就是你的React组件实例)的this。所以在箭头函数里调用this.setState,这个this就是组件本身,自然能正常调用setState方法。普通function的
this是动态绑定:在setInterval的回调函数里,普通function的this默认会指向全局对象(浏览器环境下是window,严格模式下是undefined),而不是你的组件实例。这时候你调用this.setState,相当于在window上找setState方法——当然找不到,所以就会报错。
如何让普通function版本正常运行?
如果你非要用普通function,有两种常见的解决办法:
办法1:提前保存this的引用
在setInterval外面把组件的this存到一个变量里,比如that或者self,然后在回调里用这个变量代替this:
const that = this; setInterval(function() { that.setState(previousState => { return { isShowingText: !previousState.isShowingText }; }); }, 1000);
办法2:用bind手动绑定this
把普通function通过bind(this)绑定到组件实例的this上,这样回调里的this就会指向组件了:
setInterval(function() { this.setState(previousState => { return { isShowingText: !previousState.isShowingText }; }); }.bind(this), 1000);
总结
箭头函数在这种异步回调场景下确实更省心,因为它帮你自动处理了this的继承问题。如果要用普通function,一定要记得手动处理this的绑定,不然就会出现你遇到的报错。
内容的提问来源于stack exchange,提问作者Staxks
相关产品推荐
相关产品推荐

