在componentWillUnmount中停止计时器

时间:2017-09-03 15:25:45

标签: javascript reactjs ecmascript-6

我制作了一个小倒数计时器作为React练习(对我自己而言,不是一个类或任何东西),一切正常(尽管音符总是受欢迎的),除了我注意到它仍在倒数组件已卸载。

所以现在我想让它在卸载时停止,但似乎无法正确。在卸载时停止setInterval的协议是什么?这就是我所拥有的:

class TimerVal extends Component {
  constructor(props) {
    super(props)
    this.state = {
      timeToGo: 30
    }
  }
  secondsToMMSS(seconds) {
    //returns "mm:ss"
  }
  componentDidMount() {
    setInterval(
      () => this.setState({
        timeToGo: this.state.timeToGo - 1
      }),
      1000
    )
  }
  componentWillUnmount() {
    () => this.setState({
      timeToGo: undefined
    })
  }
  render() {
    // styles
    console.log(this.state)
    const count = ( this.state.timeToGo > 0 ) ? this.secondsToMMSS(this.state.timeToGo) : "00:00"
    console.log(count)
    return(
      <div style={timerStyle}>
        <span style={timerSpanStyle}>
          {count}
        </span>
      </div>
    );
  }
}

2 个答案:

答案 0 :(得分:8)

一些事情。首先,这不是做任何事情:

() => this.setState({
  timeToGo: undefined
})

您只是定义一个匿名函数并且不执行任何操作。接下来,在倒计时停止时,不要将timeToGo设置为未定义。间隔将继续进行。相反,清除间隔:

this.interval = setInterval(
  () => this.setState({
    timeToGo: this.state.timeToGo - 1
  }),
  1000
)

然后在componentWillUnmount

clearInterval(this.interval)

这将彻底清除倒计时。最后,清除倒计时到达0时的间隔,否则它将继续运行。这需要资源:

this.interval = setInterval(
  () => {
    if(this.state.timeToGo > 0) {
      this.setState(prevState => ({
        timeToGo: prevState.timeToGo - 1
      }))
    } else {
      clearInterval(this.interval)
    }
  },
  1000
)

一旦达到0,这将清除间隔。另外,请注意我使用了prevState。由于setState是异步的,因此可以确保它访问正确的状态。

答案 1 :(得分:0)

我还有一个可以使用的选项

首先:在构造函数中向状态添加变量 idInterval 并添加函数 setTimeout

this.state = {  timeToGo: 30, idInterval: 0}
setTimeout( ()=>clearInterval(this.state.id),this.state.timeToGo)

第二:使用新引用设置变量idInterval,就这样。字节!!

ComponentDidMount() {
   const id2 = setInterval(
      ()=>(
          this.setState( {timeToGo : this.state.timeToGo -1}), 
          this.setState( {idInterval:  id2})
          ),
      1000
    )
 }