小编典典

在React中使用setState与setState

reactjs

setInterval()在React组件中使用了一个计时器,但我不确定要相对于使用开始和停止此间隔的最佳做法是什么state。我正在遇到一些异步问题。

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

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

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

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()。另一个错误(我认为是相关的)是,当我缓慢单击时,它只会每隔一次启动间隔。

谁能对此有所启发?还是他们为与异步环境setState结合使用而采取了什么措施setInterval(设置状态可以返回承诺吗?),或者哪种生命周期方法最适合此类情况?


阅读 354

收藏
2020-07-22

共1个答案

小编典典

我认为这里最大的缺陷是您state用来存储时间间隔。尽管从技术上讲是可行的,但我认为您没有理由要这样做。

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

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

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

因此,我认为您根本不需要state在此处使用。您的帖子中还有其他一些与相关的常规问题state,我将在下面尝试回答。请记住,它们与解决您的特定问题无关。


他们为避免异步问题做了setState()什么?

您可以使用一个回调来执行代码
state已设置。有一个官方的文档的部分有关这一点; 它说的是:

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

setState(nextState, callback);

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

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

通常,我们建议将componentDidUpdate()用作此类逻辑。

如果您setState的函数中有多个函数,并且想在特定事件后执行特定代码,那么使用回调函数就可以了。为了更通用,请使用上面的生命周期方法。

2020-07-22