Search code examples
reactjsreact-hooksuse-effectuse-ref

React ref.current is null in useEffect cleanup function


I'm trying to access a ref during clean up (before the component unmounts).

Like so:

const Comp = () => {
    const imgRef = React.useRef();

    React.useEffect(() => {
      console.log('component mounted', imgRef); // During mount, imgRef.current is always defined
      return () => {
        console.log('component unmounting', imgRef); // imgRef.current always null here
      }
    }, []);  // also tried adding imgRef and imgRef.current still doesn't work in clean up

    return (
      <img src={'example.png'} ref={imgRef} />
    );

};
const App = () => {
  const [img, setImg] = React.useState(true);
  return <div>
    <button onClick={() => setImg(!img)}>toggle</button>
    {img && <Comp />}
  </div>;
};
ReactDOM.render(<App />, document.querySelector('.react'));
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div class='react'></div>

Even adding imgRef in the useEffect's dependency, the imgRef.current is still null in the return of useEffect...

This works in the equivalent Class component with componentWillUnmount the imgRef is properly defined.

How can I make it work with hooks?


Solution

  • This was very helpful: https://stackoverflow.com/a/67069936

    Something like this worked for me:

    const imgRef = useRef();
    
    useEffect(() => {
      let localRef = null;
      if (imgRef.current) localRef = imgRef.current;
      return () => {
         console.log('component unmounting', localRef); // localRef works here!
      }
    }, []);
    
    return (
      <img ref={imgRef} src="example.png" />
    );