Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Understanding useRef and useEffect in this general example

So I am trying to understand useRef properly but there is one thing I am unable to wrap my head around. See this basic example

function App() {
    const [counter, setCounter] = useState(0);
    const previousCountRef = useRef(null);

    useEffect(() => {
        previousCountRef.current = counter
    },[counter]) 

    return(
        <>
        <h1>{counter}</h1>
        {previousCountRef.current !== null && (<h5>Prev: 
        {previousCountRef.current}</h5>)}  // check if previous is not null

    <button onClick={() => setCounter(counter + 1)}>CLICKME</button>
    )
    </>

}

So in this example, we increment the counter by 1 if we press the button. our useEffect only updates if we change the value of counter. Our ref variable is able to store the value of counter before it is changed.

That is the part that confuses me. How is the useEffect able to store the value of the previous counter? If we click the button, the counter is updated. Because the counter is updated, useEffect can run and gets set equal to the value of counter. How is the ref variable 1 step behind?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

On initial render, the counter variable changes from null to 0 so it runs useEffect in that situation as well, thereby setting prevCountRef.current = 0 too. They are in sync.

>Solution :

I think the answer is two parts:

  1. useEffect runs after the render. So this code previousCountRef.current = counter runs after the setCounter has completed and the component has re-rendered.
  2. Updating refs does not cause re-renders. So the code previousCountRef.current = counter does not trigger a re-render for you to see the new value in your JSX.

This leads to the ref printing one step behind, even though its actual current value may have already been updated to match the state.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading