'Implantation of counter in react has a value of 0 when I reference in an empty useEffect

I took code based off this page and adjusted it. I want to time the amount of milliseconds the user is on the component so I want to log the counter value when the component unmounts aka the return statement of useffect/componentWillUnmount().

    const [milliseconds, setMilliseconds] = useState(0);
    const isActive = useState(true);

    const logger = new logger(stuff);
  

    useEffect(() => {
        initializeIcons(undefined, { disableWarnings: true });
    });

    useEffect(() => {
        return () => {
            console.log("empty useffect milliseconds:", milliseconds);            
            logger(milliseconds);
            clearInterval(milliseconds)
        };
    }, []);

    useEffect(() => {
        let interval: NodeJS.Timeout =  setInterval(() => {
        }, 0);

        
        interval = setInterval(() => {
            setMilliseconds(milliseconds => milliseconds + 1000);
        }, 1000);
        console.log("interval:", interval);
        console.log("interval milliseconds:", milliseconds);
       
    }, [ milliseconds]);

I see the millisecond printout fine in the "interval milliseconds" console statement but the "empty useffect milliseconds:" always prints out 0. What am I doing wrong?



Solution 1:[1]

You can remember a mount timestamp and then calculate the difference.

useEffect(() => {
  const mountedAt = Date.now();

  return () => {
    const mountedMilliseconds = Date.now() - mountedAt;
    console.log(mountedMilliseconds);
  };
}, []);

Side note 1: use an empty array as deps if you want to run function on mount only. If you do not pass [] deps, your initializeIcons effect will run with each re-render. Do it like this:

useEffect(() => {
  initializeIcons(undefined, { disableWarnings: true });
}, []);

Side note 2: first interval you create creates a memory leak, because it does nothing, and is never cleared.

Another problem you have is milliseconds dependency in useEffect, which registers new intervals after each milliseconds state change.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1