'Stop an interval from another function in React

I am new to React and I try to build a timer component. 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.



Solution 1:[1]

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)
  }

Solution 2:[2]

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);

Solution 3:[3]

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....)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Shubham Khatri
Solution 2 Anadi Sharma
Solution 3 Vlad Dobrinov