我找不到在React中暂停倒数计时器的方法(“清除时间间隔”似乎无效)

时间:2019-10-18 16:35:54

标签: javascript reactjs

我正在尝试弄脏Pomodoro Clock。我现在正试图暂停计时器,但是我很难这么做。 这是App主组件中的构造函数:

this.state ={
      breakValue: 5,
      sessionValue: 25,
      time: 25*60*1000,
      isRunning: false
    }

现在,使用此功能可以开始计时了:

countDown = (timeLeft ) =>{

  this.setState({

    time : timeLeft-1000,


  })

并且我已经通过道具将该函数传递给了Controls组件:

countDown={this.countDown}

在Controls组件中,我已经像这样处理该功能:

handleStart = () =>{
 this.props.countDown(this.props.time);
    }

我为SetInterval做了一个单独的功能:



interval = () =>{
   setInterval(this.handleStart,1000)


} 

最后,我将onClick按钮附加到了最终功能:

handleSetInterval= () =>{
    this.interval();

} 

现在,计时器开始计时,倒数计时开始工作。但是如何随时暂停此计数器?我有另一个带有暂停功能的按钮,我试图用clearInterval编写一个功能,但是它不起作用。我应该使用布尔逻辑来启动/停止,还是可以在Main App组件内部处理clearInterval?我完全迷路了。谢谢大家的回答。

1 个答案:

答案 0 :(得分:0)

请记住,由于setIntreval进入队列时,这将不是一个超级精确的计时器,因此不会在1000ms时立即调用它的callBack(这只是意味着它将每1000ms排队一次)

有效的代码段(根据您的说明,请参见第二个示例,以获取更好的做法)

class Controls extends React.Component{
    state={
        myInterval : null
    }
    startTimer = () => {
        this.setState({myInterval : setInterval(this.props.countDown,1000)})
    }
    stopTimer = () => {
        clearInterval(this.state.myInterval)
    }
    render(){
        return(
            <div>
                <button onClick={this.startTimer}>Start</button>
                <button onClick={this.stopTimer}>Stop</button>
                {this.props.time}
            </div>
        )
    }
}


class App extends React.Component{
    state ={
        time: 25*60*1000
    }
    countDown = () => {
        this.setState({
            time : this.state.time-1000,
        })
    }

    render(){
        return <Controls time={this.state.time} countDown={this.countDown}/>
    }
}





ReactDOM.render(
  <App />,
  document.getElementById("react")
);
<div id='react'></div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

更好/最好的做法是将与计数器相关的所有内容移至计数器组件

如果您需要访问App中其他位置的this.state.time,请考虑useContext或Redux(根据React团队对状态进行频繁更改的App级别管理,请尝试在useContext之上使用Redux,在这种情况下)。

在应用组件级别的

setState()可能会在每次更新时重新呈现应用中的所有内容(在这种情况下,大约每1000毫秒一次)

更好的例子:

class Controls extends React.Component{
    state={
        myInterval : null,
        time: 25*60*1000
    }
    countDown = () => {
        this.setState({
            time : this.state.time-1000,
        })
    }
    startTimer = () => {
        this.setState({myInterval : setInterval(this.countDown,1000)})
    }
    stopTimer = () => {
        clearInterval(this.state.myInterval)
    }
    render(){
        return(
            <div>
                <button onClick={this.startTimer}>Start</button>
                <button onClick={this.stopTimer}>Stop</button>
                {this.state.time}
            </div>
        )
    }
}


class App extends React.Component{
    render(){
        return <Controls/>
    }
}





ReactDOM.render(
  <App />,
  document.getElementById("react")
);
<div id='react'></div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>