Devtrium

How to set an interval in React (with examples)

August 02, 20213 min read

Introduction

Using setInterval lets you execute a function at specific intervals. It's often very useful in React apps, for example for checking a condition regularly or fetching data every so often.

The code

Let's get straight to the code. This is how you use setInterval in a functional React component:

· · ·
useEffect(() => {
  const interval = setInterval(() => {
    console.log('This will be called every 2 seconds');
  }, 2000);

  return () => clearInterval(interval);
}, []);
· · ·

Read the rest of the article if you want the explanation of what's happening above!

How the setInterval code is working

There's three things to unpack:

  1. Why is setInterval called inside a useEffect hook?
  2. Why does the setInterval call look like that?
  3. Why are we returning something from the useEffect hook?

Why is setInterval called inside a useEffect hook?

According to the React docs, "The Effect Hook lets you perform side effects in function components". And that's exactly what we want to do here.

You could ask what would happen if we declared it in the component itself. Let's see that with the most famous of examples, a counter!

Let's say we want a counter that starts out at 0, and goes up by 1 every second. Something like that:

counter

The way to implement this counter using the code in the beginning of the article is the following:

import { useState, useEffect } from 'react';

export default function ExampleCounter() {
  const [counter, setCounter] = useState(0);

  useEffect(() => {
    const interval = setInterval(() => {
      setCounter((prevCounter) => prevCounter + 1);
    }, 1000);

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

  return (
    <div className="App">
      <h1>Counter: {counter}</h1>
    </div>
  );
}

A pretty straightforward functional component that holds a state in counter. The state is incremented every second thanks to the setInterval defined in the useEffect. Great.

Now what happens if I get rid of the useEffect entirely?

import { useState } from 'react';

export default function ExampleCounter() {
  const [counter, setCounter] = useState(0);

  setInterval(() => {
    setCounter((prevCounter) => prevCounter + 1);
  }, 1000);

  return (
    <div className="App">
      <h1>Counter: {counter}</h1>
    </div>
  );
}

Well, this happens:

crazy counter

That's a crazy counter all right! Can you guess what happened?

As the setInterval is defined directly inside the function Component, it gets called every time the component renders! And when does the component render? On every state change! And when does the state change? When the interval callback is called.

Oops.

So yeah, put your side effects in useEffect hooks if you don't want to have them called every time the component renders!

Why does the setInterval call look like that?

This one is pretty easy: it's simply using the web API of setInterval. There's a number of functions defined for you in the web, that you can directly use. setInterval is one of them.

Simply look it up on Google, and you'll get an example of how to use it pretty fast!

The function takes two arguments:

  1. The first is a function that will get called at specified intervals.
  2. The second is the interval, in milliseconds.

Why are we returning something from the useEffect hook?

As a reminder, when we want to do some actions when a component is destroyed, we define it in a function which is returned in a useEffect.

A very common use case of this is clearing up effects like intervals.

Why do we need to clear intervals? Well, imagine we don't clear it. The component is destroyed, but the interval still runs! And it's trying to set a state that doesn't exist anymore.

This isn't too big of a deal by itself (React will just ignore it), but it's still a memory leak. Now imagine the component is created and destroyed again and again. You could get dozens of setIntervals running! Taken together, this could seriously slow down your app.

That's why the web API that gives us setInterval also provides us with a clearInterval function. And that's why you call it in the return statement of useEffect!

Wrapping up

I hope you have a better idea of how to use setInterval in React! It's a very useful tool to have in your box, but can lead to bugs when not used properly.

If you still have some questions or things that aren't clear, please feel free to reach out on Twitter!

Package versions at the time of writing

Did you enjoy this article?

If so, a quick share on Twitter could really help out!