React ref.current is null in useEffect cleanup function [duplicate]
Asked Answered
L

1

5

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?

Ludovika answered 21/4, 2022 at 2:21 Comment(6)
I made you a live snippet and, as you see, can't reproduce the problem - can you edit the snippet so that it demonstrates the problem you describe? (A const with an object initially assigned to it should never be undefined, so I'm doubtful...)Ansilme
@Ansilme codesandbox.io/s/compassionate-sun-uhv98fDispense
Thanks @SteveK I was about to share this I just made: codesandbox.io/s/ref-undefined-clean-up-useeffect-me3j01?file=/… But yours shows the same result - when the component unmounts ref.current is nullLudovika
It's not undefined as your question says, it's null. Fix it with: stackoverflow.com/a/67069936Ansilme
@Ludovika you can set the current ref as a constant before you return the cleanup function and then reference it in the return function. So set const img = imageRef.current before the return and then you can access it in the return function.Dispense
Thanks! Those solutions solved my problemLudovika
L
6

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" />
);
Ludovika answered 21/4, 2022 at 2:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.