在React中使用setState的setInterval [英] setInterval with setState in React

查看:951
本文介绍了在React中使用setState的setInterval的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a timer using setInterval() in a React component and I'm unsure what the best practices are in order to start and stop this interval in respect to using state. I'm running into some asynchronous issues with that.

假设我的React组件中有一组链接可以呈现并执行回调:

Let's say I have a set of links in my React component that render and execute the callback fine:

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

这是 switchNums () function,我希望它重置现有的计时器:

Here's the switchNums() function, where i want it to reset an existing timer:

switchNums(num){
  this.stopTimer()
  this.reset(num)
}

这是 startTimer() stopTimer() reset()

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())
}

其中一个错误就是快速点击链接会导致多个间隔点开,尽管 if startTimer()中的条件。我猜这与 setState()的异步性质有关。另一个错误(我认为相关)是当我慢慢点击时,它只会每隔一段时间开始一次。

One of the bugs is clicking on the links rapidly will cause multiple intervals to fire despite the if condition in startTimer(). I'm guessing this has to do with the asynchronous nature of setState(). Another bug (and I think related) is that when i click slowly, it only starts the interval every other time.

任何人都可以对此有所了解吗?或者他们采取了什么来绕过异步问题 setState setInterval 一起使用(任何方式设置状态都可以返回一个承诺?),或者哪种生命周期方法最适合这种情况?

Can anyone shed some light on this? Or what they've done to circumvent asynchronous issues with setState being used in conjunction with setInterval(any way set state can return a promise?), Or which lifecycle methods would be best for this type of situation?

推荐答案

我认为这里最大的缺陷是你正在使用来存储您的间隔。虽然技术上可行,但我认为没有理由你真的想要这样做。

I think the biggest flaw here is that you're using state to store your interval. While technically possible, I see no reason why you would actually want to do that.

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

Instead, just use a local variable to your component:

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

stopTimer(){
  clearInterval(this.timerId);
}

所以我认为你不需要使用在这里为您的计时器。您的帖子中还有一些其他一般性问题虽然与有关,但我会尝试回答以下问题。请记住,它们与解决您的特定问题无关。

So I don't think you need to use the state at all here for your timer. You have some other general questions in your post though that are related to state, and I'll try to answer those below. Just bear in mind that they are irrelevant in solving your particular issue.

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

What have they've done to circumvent asynchronous issues with setState()?

您可以使用回调来执行代码 之后状态已设置。有关于此的官方文档部分;这就是它所说的:

You can use a callback to execute code after the state has been set. There's a section of the official docs about this; here's what it says:


第二个参数是一个可选的回调函数,一旦完成setState并重新渲染组件,它将被执行。

The second parameter is an optional callback function that will be executed once setState is completed and the component is re-rendered.



setState(nextState, callback);






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

上述文档的相同部分仍在继续:

The same section of the doc as above continues:


一般来说,我们建议使用componentDidUpdate()代替这样的逻辑。

Generally we recommend using componentDidUpdate() for such logic instead.

如果你有多个 setState ,并且你想在特定事件后执行特定代码,我认为你使用回调很好。为了更一般的目的,请使用上面的生命周期方法。

If you have multiple setState in your function, and you want to execute specific code after a specific event, I think you're fine using the callback. For more general purposes use the life-cycle method above.

这篇关于在React中使用setState的setInterval的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆