How to use setInterval() method inside React components

Learn how to properly use setInterval() and clearInterval() methods in React components

Posted on July 14, 2021


Sometimes, you may want to run the setInterval() method inside a React component so that the component may run a piece of code at specific intervals.

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 function component for its code examples. For the class component equivalent, refer to this tutorial:

How to use setInterval() method inside React class components

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

Run setInterval() once the component is mounted

If you want the interval to start as soon as your component is rendered on the screen, you can put your setInterval() method inside a useEffect() hook.

The code can be as simple as follows:

useEffect(() => {
  setInterval(() => {
    /*
        Run a function or set any state here
    */
  }, 1000);
}, []);

By combining the setInterval() method with useEffect and useState hooks, you can create a timer that counts how many seconds have passed since the component has mounted.

Inside the following App component:

import React, { useState, useEffect } from "react";

const App = () => {
  const [count, setCount] = useState(0);

  useEffect(() => {
    setInterval(() => {
      setCount(prevCount => prevCount + 1);
    }, 1000);
  }, []);

  return <h1>The component has been rendered for {count} seconds</h1>;
};

export default App;

Since the useEffect() hook above has an empty dependency array ([]), it will be executed only once during the lifetime of the component, calling the setInterval() method to run the setCount() method once every 1000 milliseconds.

Please note that you need to use the previous state value passed into the setCount() method to constantly increment the count value.

If you increment the count value as follows:

setCount(count + 1);

The the count will stuck at 0 + 1 = 1 because the variable count value when setInterval() is called is 0.

If you want to clear the setInterval() method and avoid memory leak, then you need to do two things:

  • Keep the interval ID returned by the setInterval() method in a variable
  • Modify the useEffect() hook to return a function that calls the clearInterval() method, passing the interval ID previously returned by the setInterval() method.

Here’s the modified useEffect() hook implementing the two steps above:

useEffect(() => {
  const intervalId = setInterval(() => {
    setCount(prevCount => prevCount + 1);
  }, 1000);

  return () => clearInterval(intervalId);
}, []);

And that’s how you can run the setInterval() method as soon as the component mounts. Now let’s see how to run the setInterval() method when the user clicks on a button.

Run setInterval() from a React button onClick event

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

Here’s an example:

const App = () => {
  const [count, setCount] = useState(0);

  const handleClick = () => {
    setInterval(() => {
      setCount(prevCount => prevCount + 1);
    }, 1000);
  }

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

export default App;

To stop the interval with a button click, you need to save the interval ID returned by the setInterval() method as a state value.

For example, let’s create another state named intervalId as follows:

const [intervalId, setIntervalId] = useState(0);

const handleClick = () => {
  const newIntervalId = setInterval(() => {
    setCount(prevCount => prevCount + 1);
  }, 1000);
  setIntervalId(newIntervalId);
}

Next, modify the handleClick() function and add an if block that checks for the intervalId value first.

If the intervalId value is truthy, then:

  • Call the clearInterval() method and pass the intervalId as its argument
  • Call setIntervalId() and set the value back to 0
  • Write the return statement to stop the handleClick() function execution

The code below implements the three steps above:

const handleClick = () => {
  if(intervalId) {
    clearInterval(intervalId);
    setIntervalId(0);
    return;
  }

  const newIntervalId = setInterval(() => {
    setCount(prevCount => prevCount + 1);
  }, 1000);
  setIntervalId(newIntervalId);
}

Finally, update the button label to Start counting or Stop counting depending on the intervalId value.

Here’s the complete code:

const App = () => {
  const [count, setCount] = useState(0);
  const [intervalId, setIntervalId] = useState(0);

  const handleClick = () => {
    if (intervalId) {
      clearInterval(intervalId);
      setIntervalId(0);
      return;
    }

    const newIntervalId = setInterval(() => {
      setCount(prevCount => prevCount + 1);
    }, 1000);
    setIntervalId(newIntervalId);
  };

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

export default App;

And that’s how you can use the setInterval() method properly inside a React function 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