News for hackers. Stuff that matters.
Re:Thinking in React Hooks by andrewstuart on Thursday December 12, 2019 @10:08PM (#21778836)
This should work:

  import React, {useState, useEffect} from 'react';
  
  const CounterComponent = React.memo(() => {
    const [counter, setcounter] = useState(0);
  
    useEffect(
      () => {
        let counterTimer = null;
        const incrementCounter = () => setcounter(counter + 1);
  
        // counterTimer is null if it has not yet been started
        if (counterTimer === null) {
          counterTimer = setInterval(incrementCounter, 1000);
        }
  
        // Remove event listener on cleanup - note the remove function signature needs to match the add function sig
        return () => clearInterval(counterTimer);
    }, [counter]
    );

    return <span>{counter}<br/></span>;
});

  export {CounterComponent};
Re:Thinking in React Hooks by steve_taylor on Thursday December 12, 2019 @10:56PM (#21779038)
But you're setting up and tearing down an interval each time counter changes, so it's no better than setTimeout. Compared to a single setInterval, it's going to gradually drift over time.

counterTimer is always going to be null where you're checking it for null.

You can't really do it properly without also using useRef to track the value. The reason is that the object returned by useRef is always the same, so it's never stale.

Re:Thinking in React Hooks by andrewstuart on Friday December 13, 2019 @12:29AM (#21779339)
Ah yes I recall.

The key thing to understand about doing this is to set the state in a context, and do the displaying in another component. There's no point in trying to get the component to re-render when the time value updates. That's the wrong way to program react.