hitchhiker
hitchhiker

Reputation: 1319

Does clearing timeout/interval have to be inside `useEffect` react hook?

I'm wondering what is the correct way and best practice to clear timeouts/intervals when using React hooks. For example I have the following code:

import React, { useState, useEffect, useRef } from 'react';

const Test = () => {
  const id = useRef(null)
  const [count, setCount] = useState(5)
  const [timesClicked, setTimesClicked] = useState(0)

  if (!count) {
    clearInterval(id.current)
  }

  useEffect(() => {
    id.current = setInterval(() => {
      setCount(count => count -1)
    }, 1000)

    return () => {
      clearInterval(id.current)
    }
  }, [])

  const onClick = () => setTimesClicked(timesClicked => timesClicked + 1)

  return (
    <div>countdown: {count >= 0 ? count : 0}
      <hr />
      Clicked so far: {timesClicked}
      {count >= 0 && <button onClick={onClick}>Click</button>}
    </div>
  )
}

When count equals 0 the interval is cleared in the body of the Test function. In most of the examples I've seen on the Internet interval is cleared inside useEffect, is this mandatory?

Upvotes: 4

Views: 1316

Answers (2)

Niko Modric
Niko Modric

Reputation: 665

You must be sure to clear all intervals before your component gets unmounted. Intervals never disappear automatically when components get unmounted and to clear them, clearInterval is often called inside useEffect(() => {}, []).

The function retured in useEffect(() => {}, []) gets called when the compoment is unmounted.

    return () => {
      clearInterval(id.current)
    }

You can see that intervals set inside a component never disappears automatically by checking this sandbox link. https://codesandbox.io/s/cool-water-oij8s

Intervals remain forever unless clearInterval is called.

Upvotes: 5

Lajos Arpad
Lajos Arpad

Reputation: 76905

setInterval is a function which is executed repeatedly and it returns an id of the interval. When you call clearInterval with this id, you stop that function from repeating. It's not mandatory to do it inside a certain function, you need to clear it when you no longer want that function to be called subsequently. You can call it in the function you return as a result of useEffect, if that's what you need.

Upvotes: 1

Related Questions