如何在React中修复setInterval?西蒙说游戏定时器问题求助
解决React Simon Says游戏中定时器的
this上下文问题 嘿,我看了你的代码,核心问题出在定时器回调函数里的this上下文丢失了——普通的function()会创建自己的this,不再指向你的React组件实例,所以调用this.setState或者访问this.state、this.playStep都会失效甚至报错。下面给你具体的修复方案:
1. 修复playStep里的setTimeout
把setTimeout里的普通函数换成箭头函数,箭头函数不会绑定自己的this,会继承外层作用域的this(也就是你的组件实例):
playStep(step) { this.setState({ clickClass: "button hover" }); this.sounds[step].play(); // 换成箭头函数,保留组件的this上下文 setTimeout(() => { this.setState({ clickClass: "button" }); }, 300); }
2. 修复showSteps里的setInterval
同样的道理,把setInterval的回调换成箭头函数,同时注意num变量的作用域(这里用let已经能保证作用域正确):
showSteps() { this.setState({ gameConsole: this.state.round }); let num = 0; // 箭头函数保留组件this let moves = setInterval(() => { this.playStep(this.state.steps[num]); this.setState({ gameConsole: "Wait..." }); num++; if (num >= this.state.steps.length) { this.setState({ gameConsole: "Repeat the steps!" }); clearInterval(moves); } }, 600); // 把定时器实例存到组件上,方便后续清除 this.movesTimer = moves; }
额外的最佳实践:避免内存泄漏
为了防止组件卸载后定时器仍在运行导致内存泄漏,记得在组件卸载时清除定时器:
componentWillUnmount() { if (this.movesTimer) { clearInterval(this.movesTimer); } }
如果你更习惯用普通函数写法,也可以手动绑定this,比如:
setTimeout(function(){ this.setState({ clickClass: "button" }); }.bind(this), 300);
不过箭头函数的写法更简洁直观,也是现在React开发中的常用方式。
内容的提问来源于stack exchange,提问作者oscicen
相关产品推荐
相关产品推荐

