0

I am trying to log the latest value of state variable 'count'. The logging function is invoked by 'setInterval' function in useEffect hook. The state variable 'count' is updated by click of a button.

I am seeing the logged value as always zero, no matter how many times I click the button.

Why is this happening and how can it be fixed without using useRef? The code is also on codesandbox

export default function App() {
  const [count, setCount] = useState(0);

  const handleClick = () => {
    setCount((count) => count + 1);
  };

  useEffect(() => {
    let handle = setInterval(log, 5000);

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

  const log = () => {
    console.log(count);
  };

  return (
    <div className="App">
      <p>{count}</p>
      <button onClick={() => handleClick()}>Add 1 </button>
    </div>
  );
}
A Singh
  • 107
  • 7

1 Answers1

0

Your setInterval only gets the value of count once, when the component gets mounted with useEffect. So it's always zero. You should work with refs instead to get the current value of count from the DOM. Something like that:

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

export default function App() {
  const [count, setCount] = useState(0);
  const myref = useRef(0);

  const handleClick = () => {
    setCount((count) => count + 1);
  };

  useEffect(() => {
    let handle = setInterval(log, 5000);

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

  const log = () => {
    console.log(myref.current.innerHTML);
  };

  return (
    <div className="App">
      <p ref={myref}>{count}</p>
      <button onClick={() => handleClick()}>Add 1 </button>
    </div>
  );
}
MWO
  • 2,627
  • 2
  • 10
  • 25
  • `Your setInterval only gets the value of count once` Why does this happen with only count, since myref.current receives correct value. – A Singh Dec 07 '21 at 19:22
  • Because myref.current is a reference to the actual Dom element. it will be evaluated every time this element gets updated in the Dom. count on the other hand is the actual value which is zero at the time when the component is mounted. – MWO Dec 07 '21 at 19:29
  • I have modified the code to use 'ref' as an instance variable and then log that instance variable, [codesandbox](https://codesandbox.io/s/setinterval-closure-question-6qom5). Why does setInterval close over state variable but not instance variable? – A Singh Dec 08 '21 at 13:19