You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 09:05:34