Search code examples
reactjsuse-effect

What is the difference between using ref vs ref.current within useEffect?


I have the following ref variable :

const renderRefs = useRef()

What is the differenece beetween using:

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

and

  useEffect(() => {
   
  }, [renderRefs])

Solution

  • Assuming you meant to refer to the same ref -

    The ref object returned by useRef is stable. It will not change across re-renders. Since it's always the same, this

    useEffect(() => {
    
    }, [refItem])
    

    is equivalent to

    useEffect(() => {
    
    }, [])
    

    Whatever exists in the .current property of the ref may well change across re-renders, depending on how the ref is used. Putting the .current property in the dependency array means: "After a re-render, if the value has changed since the prior render, run the effect callback."

    For example, if you had

    <button
      onClick={() => {
        refItem.current = 5;
        setSomeState('abc');
      }}
      ...
    

    clicking the button would result in a re-render due to setSomeState, and then if the ref value used to be something other than 5 on the last render, React will detect a change in the dependency array and run the effect callback.

    If the ref value used to be 5 on the last render, then doing refItem.current = 5 inside the click handler above means that the effect callback will not run after the next render, because the previous value of 5 is equal to the current value of 5.

    Setting state is important. If you don't set state, the component won't re-render, and if the component doesn't re-render, the dependency array values aren't checked (nor does anything else occur). So, doing only

    <button
      onClick={() => {
        refItem.current = 5;
      }}
      ...
    

    is not sufficient to trigger the effect callback.