最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Stop an interval from another function in React - Stack Overflow

programmeradmin4浏览0评论

I am new to React and I try to build a timer ponent. Now I have the start function working but I would also like to stop the timer by an onclick handler. The problem is that the start function uses an interval, but I don't know how to stop that interval from another function.

My JS code

  constructor() {
    super();

    this.state = {
      times: [],
      timer: false,
      currentTimer: 0
    }

    this.startTimer = this.startTimer.bind(this);
    this.stopTimer = this.stopTimer.bind(this);

  }

  startTimer() {

    const start = Date.now();

    this.setState({ timer: true });

    var timer = setInterval(() => {

      let time = new Date() - start;

      this.setState({ currentTimer: Math.round(time / 1000)});


    }, 1000);

  }

  stopTimer() {

    this.setState({ timer: false });
    console.log('stopped');

    //Clear interval here

  }

I know that the timer variable is the identifier of that interval but how can I access it and then stop it? I have tried almost everything but nothing seems to work and I just don't know how I can fix that.

I am new to React and I try to build a timer ponent. Now I have the start function working but I would also like to stop the timer by an onclick handler. The problem is that the start function uses an interval, but I don't know how to stop that interval from another function.

My JS code

  constructor() {
    super();

    this.state = {
      times: [],
      timer: false,
      currentTimer: 0
    }

    this.startTimer = this.startTimer.bind(this);
    this.stopTimer = this.stopTimer.bind(this);

  }

  startTimer() {

    const start = Date.now();

    this.setState({ timer: true });

    var timer = setInterval(() => {

      let time = new Date() - start;

      this.setState({ currentTimer: Math.round(time / 1000)});


    }, 1000);

  }

  stopTimer() {

    this.setState({ timer: false });
    console.log('stopped');

    //Clear interval here

  }

I know that the timer variable is the identifier of that interval but how can I access it and then stop it? I have tried almost everything but nothing seems to work and I just don't know how I can fix that.

Share Improve this question asked Mar 1, 2018 at 11:50 GiesburtsGiesburts 7,66616 gold badges52 silver badges92 bronze badges
Add a ment  | 

4 Answers 4

Reset to default 5

To stop the timer, you need the timer id, So First job will be to store the id in such a way that it should be accessible in all the class methods. Second job will be use clearInterval to clear the timer (timer id will be required here).

One option is, Store the timer id in class instance.

Like this:

startTimer() {
    const start = Date.now();
    this.setState({ timer: true });
    // storing the id
    this.timerID = setInterval(() => {
        let time = new Date() - start;
        this.setState({ currentTimer: Math.round(time / 1000)});
    }, 1000);
}

stopTimer() {
    this.setState({ timer: false });
    clearInterval(this.timerID);
}

Working code:

class App extends React.Component {

  constructor(){
     super();
     this.state = {currentTimer: ''}
     this.startTimer = this.startTimer.bind(this);
     this.stopTimer = this.stopTimer.bind(this);
  }
  
  startTimer() {
    const start = Date.now();
    this.timerID = setInterval(() => {
        let time = Math.random() * 10;
        this.setState({ currentTimer: time});
    }, 1000);
  }

  stopTimer() {
     clearInterval(this.timerID);
  }
  
  render(){
     return (
        <div>
          Value: {this.state.currentTimer || '0'}
          <br />
          <button onClick={this.startTimer}>Start timer</button>
          <button onClick={this.stopTimer}>Stop timer</button>
        </div>
     )
  }

}

ReactDOM.render(<App />, document.getElementById('app'))
<script src="https://cdnjs.cloudflare./ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare./ajax/libs/react/15.1.0/react-dom.min.js"></script>

<div id='app' />

Save the timerId as a class instance variable which can then be accessed from other functions and used to clear the interval

constructor() {
    super();

    this.state = {
      times: [],
      timer: false,
      currentTimer: 0
    }
    this.timer = null;

    this.startTimer = this.startTimer.bind(this);
    this.stopTimer = this.stopTimer.bind(this);

  }

  startTimer() {

    const start = Date.now();

    this.setState({ timer: true });

    this.timer = setInterval(() => {

      let time = new Date() - start;

      this.setState({ currentTimer: Math.round(time / 1000)});


    }, 1000);

  }

  stopTimer() {

    this.setState({ timer: false });
    console.log('stopped');

    //Clear interval here
    clearInterval(this.timer)
  }

Your timer variable is a local variable to startTimer() method, it stores the identifier of that interval but is not accessible outside the function scope.

To fix this, add following in constructor() method:

this.timer = null;

Then, in startTimer() method change:

var timer = setInterval(() => {

  let time = new Date() - start;

  this.setState({ currentTimer: Math.round(time / 1000)});


}, 1000);

to:

this.timer = setInterval(() => {

  let time = new Date() - start;

  this.setState({ currentTimer: Math.round(time / 1000)});


}, 1000);

Finally, add following in stopTimer() method:

//Clear interval here code here
clearInterval(this.timer);

Not sure if it`s the right approach, but if you look for a quick workaround, just make it global(outside Component). It works, soooo....)

Edit : in Functional Components you have to use useRef()

link to ReactDOC: https://reactjs/docs/hooks-faq.html#is-there-something-like-instance-variables

发布评论

评论列表(0)

  1. 暂无评论