在React类中清除间隔

时间:2017-11-12 21:21:18

标签: javascript reactjs ecmascript-6 clearinterval

因此,我们有一个简单的React组件,它从父组件接收一个整数。单击该按钮时,我们会在屏幕上显示整数并开始倒计时。

问题是如何停止倒计时。在阅读其他SO帖子时,我发现了clearInterval(),但似乎我在这里遗漏了一些东西。

非常感谢任何帮助。如果有人能够向我解释为什么示例代码没有按预期工作,将会获得奖励升值积分。

    import React from "react";

    export default class TestInterval extends React.Component {
        constructor(props) {
            super(props);
            this.state = {
                countDown: this.props.countDown, // An integer from father component
            }
        }

        timer = () => {
            setInterval(() => {
                if (this.state.countDown === 0) {
                    this.stopCountDown();
                }
                this.setState( prevState => ({
                    countDown: prevState.countDown - 1, 
                }));
            }, 1000)
        }

        startCountDown = () => {
            this.timer();
        }

        stopCountDown = () => {
            clearInterval(this.timer); // Not working
        }

        render () {
            return (
                <div>
                    <button onClick={this.startCountDown}>
                        Start Countdown
                    </button>
                    <p>{this.state.countDown}</p>
                </div>
            );
        }
    }

1 个答案:

答案 0 :(得分:2)

您需要存储从setInterval返回的间隔参考 来自docs

  

它返回一个唯一标识间隔的间隔ID,所以   您可以稍后通过调用clearInterval()来删除它。

所以你的代码应该是这样的,例如:

this.interval = setInterval(() => {...

然后清除它:

 clearInterval(this.interval);

我会在状态真正设置(setState异步)之后检查条件,你可以在setState的回调中执行。

this.interval = setInterval(() => {
      this.setState(prevState => ({
        countDown: prevState.countDown - 1,
      }), () => {
        if (this.state.countDown === 0) {
          this.stopCountDown();
        }
      });
    }, 1000)

运行示例:

class TestInterval extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      countDown: this.props.countDown, // An integer from father component
    }
  }

  timer = () => {
    this.interval = setInterval(() => {
      this.setState(prevState => ({
        countDown: prevState.countDown - 1,
      }), () => {
        if (this.state.countDown === 0) {
          this.stopCountDown();
        }
      });
    }, 1000)
  }

  startCountDown = () => {
    this.timer();
  }

  stopCountDown = () => {
    clearInterval(this.interval); // Not working
  }

  render() {
    return (
      <div>
        <button onClick={this.startCountDown}>
          Start Countdown
                    </button>
        <p>{this.state.countDown}</p>
      </div>
    );
  }
}

ReactDOM.render(<TestInterval countDown={3} />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>