How to use setInterval() method inside React class components

Use setInterval() and clearInterval() methods in React class components

Posted on July 15, 2021


This tutorial will show you how to run the setInterval() method as soon as your component is mounted (rendered) on the screen or when a button is clicked by the user.

This tutorial uses React class component for its code examples. For the function component equivalent, you can refer to this tutorial:

How to use setInterval() method inside React components

Let’s begin with starting the interval when the component is mounted.

React class component, calling setInterval() on mount

To start the interval as soon as the class component has been rendered on the screen, you need to call the setInterval() method inside the componentDidMount() lifecycle method.

Here’s a pattern for using the setInterval() method:

componentDidMount() {
    setInterval(() => {
      /*
          Run any function or setState here
      */
    }, 1000);
  }

You can call the this.setState() method inside the setInterval() method to increment a previous state property value.

The following example uses the state property count value as a timer that counts how many seconds have passed since the component has been rendered on the screen:

class App extends React.Component {
  state = { count: 0 };

  componentDidMount() {
    const intervalId = setInterval(() => {
      this.setState(prevState => {
        return {
          count: prevState.count + 1,
        };
      });
    }, 1000);
  }

  componentWillUnmount(){
    clearInterval(intervalId);
  }

  render() {
    return (
      <h1>The component has been rendered for {this.state.count} seconds</h1>
    );
  }
}

export default App;

The value of the count property above will be incremented by 1 every 1000 milliseconds.

To stop the interval when the component is destroyed, you need to call the clearInterval() method from inside the componentWillUnmount() lifecycle method.

First, you need add a new property to the state object named intervalId and set the initial value to 0:

state = { count: 0, intervalId: 0 };

Next, save the interval ID returned from the setInterval() method as the intervalId state value.

The complete code for the componentDidMount() method is as follows:

componentDidMount() {
  const newIntervalId = setInterval(() => {
    this.setState(prevState => {
      return {
        ...prevState,
        count: prevState.count + 1,
      };
    });
  }, 1000);

  this.setState(prevState => {
    return {
      ...prevState,
      intervalId: newIntervalId,
    };
  });
}

Although it looks complicated, the additional code only calls the setState() method to assign the newIntervalId value as the state.intervalId value.

The prevState value is expanded on the new state returned from the setState() method so that the count property won’t be removed from the state itself.

And that’s how to clear the interval before unmounting the component. Now let’s see how you can start and stop the interval method from a button click.

React class component, calling setInterval() on button click

To start the setInterval() method when the user clicks on a button, you need to put the setInterval() method call inside the button’s onClick event handler property.

In essence, you only need to place the code inside the componentDidMount() method above as the code you run when the button is clicked.

Take a look at the following code:

class App extends React.Component {
  state = { count: 0, intervalId: 0 };

  handleClick = () => {
    const newIntervalId = setInterval(() => {
      this.setState(prevState => {
        return {
          ...prevState,
          count: prevState.count + 1,
        };
      });
    }, 1000);
    
    this.setState(prevState => {
      return {
        ...prevState,
        intervalId: newIntervalId,
      };
    });
  }

  render() {
    return (
      <div>
        <h1>The component has been rendered for {this.state.count} seconds</h1>
        <button onClick={this.handleClick}>Start counter</button>
      </div>
    );
  }
}

export default App;

To stop the interval, you need to add an if block inside the handleClick() method above.

If the state.intervalId value is not zero (truthy) then you need to do the following steps:

  • Call the clearInterval() method passing the state.intervalId as its argument
  • Call the setState() method and set the intervalId value back to 0
  • Stop executing the handleClick() method by using the return statement

Here’s the code implementing the above steps:

handleClick = () => {
  if(this.state.intervalId){
    clearInterval(this.state.intervalId);
    this.setState(prevState => {
      return {
        ...prevState,
        intervalId: 0,
      };
    });
    return;
  }
  
  const newIntervalId = setInterval(() => {
    this.setState(prevState => {
      return {
        ...prevState,
        count: prevState.count + 1,
      };
    });
  }, 1000);
  
  this.setState(prevState => {
    return {
      ...prevState,
      intervalId: newIntervalId,
    };
  });
}

Don’t forget to update the button’s label to Start counting or Stop counting depending on the state.intervalId value:

<button onClick={this.handleClick}>
  {this.state.intervalId? "Stop counter": "Start counter"}
</button>

The full code for the class component is as shown below:

class App extends React.Component {
  state = { count: 0, intervalId: 0 };

  handleClick = () => {
    if(this.state.intervalId){
      clearInterval(this.state.intervalId);
      this.setState(prevState => {
        return {
          ...prevState,
          intervalId: 0,
        };
      });
      return;
    }
    
    const newIntervalId = setInterval(() => {
      this.setState(prevState => {
        return {
          ...prevState,
          count: prevState.count + 1,
        };
      });
    }, 1000);
    
    this.setState(prevState => {
      return {
        ...prevState,
        intervalId: newIntervalId,
      };
    });
  }

  render() {
    return (
      <div>
        <h1>The component has been rendered for {this.state.count} seconds</h1>
        <button onClick={this.handleClick}>
          {this.state.intervalId? "Stop counter": "Start counter"}
        </button>
      </div>
    );
  }
}

export default App;

And that’s how you can call the setInterval() method with a button click inside a React class component.

Related articles:

Level up your React skill today 🔥

Build FOUR projects using React with my latest book.

Structured knowledge from beginner to experienced level!

Learn more