Home > OS >  Confused in using clearInterval() inside useEffect in React
Confused in using clearInterval() inside useEffect in React

Time:02-02

function TimeArea() {
  const [theTime, setTheTime] = useState(new Date().toLocaleString())

  // Confused here!
  useEffect(() => {
    const interval = setInterval(() => setTheTime(new Date().toLocaleString()), 1000)
    return () => clearInterval(interval)
  }, [])

  return <p>The current time is {theTime}.</p>
}

Why would it still output {theTime} in the paragraph <p></p> when we're just storing setInterval inside a variable? and even more so we cleared it before executing the 'interval' variable? How come it would still output time intervals of 1second. Also, I'm confused with the "mount/unmount" terms which is relevant to this problem when I was searching google. I only understand that mount is when the page 'loads' and unmount is when 'closing' or 'switching' to a different page. Forgive me everyone, I really tried searching it on youtube and google as well as the all knowing chatgpt, but I am still confused.

CodePudding user response:

The interval is cleared only when react removes the component from the page (unmount). Mount/unmount in react refer to the individual component, not the entire page.

Why would it still output {theTime} in the paragraph <p></p> when we're just storing setInterval inside a variable?

The interval constant doesn't hold the value. It stores the id of the interval, that allows you to clear the interval. Add console.log(interval) to the useEffect block, and you'll see that it's not time value, and it doesn't update all the time.

Every 1000ms (the interval) the function setTheTime(new Date().toLocaleString()) is called, and updates theTime (sets the state). Setting the state also causes a re-render, and the paragraphs is re-rendered with the new value.

If you only want the date to update on load, use a reference instead:

const { useRef } = React

function TimeArea() {
  const theTime = useRef(new Date().toLocaleString())

  return <p>The current time is {theTime.current}.</p>
}

ReactDOM
  .createRoot(root)
  .render(<TimeArea />);
<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>

<div id="root"></div>

  • Related