Javascript 在React中设置setState的setInterval

Javascript 在React中设置setState的setInterval,javascript,reactjs,Javascript,Reactjs,我在React组件中有一个使用setInterval()的计时器,我不确定在使用状态方面启动和停止此间隔的最佳做法是什么。我在这方面遇到了一些异步问题 假设我的React组件中有一组链接,用于呈现和执行回调: let links = [10, 50, 100, 500, 1000].map((num) => { return( <Link key={num} onClick={(e) => this.switchNums(num)} to={`/somePath/$

我在React组件中有一个使用
setInterval()
的计时器,我不确定在使用
状态方面启动和停止此间隔的最佳做法是什么。我在这方面遇到了一些异步问题

假设我的React组件中有一组链接,用于呈现和执行回调:

let links = [10, 50, 100, 500, 1000].map((num) => {
  return(
    <Link key={num} onClick={(e) => this.switchNums(num)} to={`/somePath/${num}`}>{num}</Link>
  )
})
以下是
startTimer()
stopTimer()
reset()

其中一个错误是,尽管
startTimer()。我猜这与
setState()
的异步性质有关。另一个bug(我认为是相关的)是,当我缓慢单击时,它只会每隔一次启动间隔


有人能解释一下吗?或者他们做了什么来规避异步问题,将
setState
setInterval
结合使用(设置状态可以返回承诺吗?),或者哪种生命周期方法最适合这种情况?

我认为这里最大的缺陷是您使用
state
来存储间隔。虽然从技术上讲是可能的,但我看不出你有什么理由真的想这么做

相反,只需对组件使用局部变量:

startTimer(){
  if(!this.timerId){     
    this.timerId = setInterval(()=>{
      //your function
    }, 1000);
  }
}

stopTimer(){
  clearInterval(this.timerId);
}
因此,我认为您根本不需要在这里为计时器使用
状态。你的帖子中还有一些与州相关的一般性问题,我将在下面尝试回答这些问题。请记住,它们与解决您的特定问题无关


他们用
setState()
做了什么来规避异步问题?

设置
状态后,可以使用回调执行代码。关于这一点,有一个很好的解释;它是这样说的:

第二个参数是一个可选的回调函数,它将在setState完成并重新呈现组件后执行


哪种生命周期方法最适合这种情况?

上述文件的同一部分继续:

通常,我们建议对此类逻辑使用componentDidUpdate()


如果函数中有多个
setState
,并且希望在特定事件后执行特定代码,我认为可以使用回调。出于更一般的目的,请使用上述生命周期方法。

使用React钩子
useState
useEffect
可以执行以下操作:

const[timer,setTimer]=useState(1);
useffect(()=>{
const timerId=setInterval(()=>setTimer(timer+1),1000);
return()=>clearInterval(timerId);
});

天哪,你可以把东西存储在组件本身中。。。非常感谢。我会试试的谢谢你!这很有效。这可能是另一个问题,但除了组件的状态或道具之外,还有哪些东西是组件的属性呢?(除方法外)默认为无。请记住,
state
props
实际上是
this
对象的属性(您将它们键入为
this.state
this.props
)--您的
this.timer
变量也是如此。
状态
道具
都应该只包含数据,如果更改这些数据,就会触发组件的重新呈现。换句话说,如果不是数据直接(或至少直接)影响组件的渲染输出,那么它不应该是
状态
道具的一部分
@chris感谢您添加设置状态(nextState,callback);在你的回答中。这节省了我很多时间
startTimer(){
  if(!this.state.timerId){      
    let timerId = setInterval(()=>{
      let timer = this.state.timer + 1
      this.setState({
        timer: timer,
        timerId: timerId
      })
    }, 1000)
  }
}

stopTimer(){
  clearInterval(this.state.timerId)     
  this.setState({timerId:null})
}

reset(size){
  this.setState({
    gameOver: false,
    counter: 0,
    correct: 0,
    numbers: this.getRandomNumbers(size),
    timer: 0
  }, this.startTimer())
}
startTimer(){
  if(!this.timerId){     
    this.timerId = setInterval(()=>{
      //your function
    }, 1000);
  }
}

stopTimer(){
  clearInterval(this.timerId);
}
setState(nextState, callback);