1

Since I do not understand React and HTML rendering behavior entirely, I'm unsure is there a potential issue with React refs being potentially null if they are accessed from function wrapped with window.requestAnimationFrame, that in turn is called from event listener that component subscribes on mount and un-subscribes on unmount. I present a small code snippet that better illustrates the logical uncertainty I face:

export const MyComponent: React.FunctionComponent = () => {

    const divRef = useRef<HTMLDivElement | null>(null);

    const doSomethingWithRef = (): void => {
        // This is my uncertainty:
        //    Can this ever be called AFTER unmount has happened, so that divRef.current is null?
        console.log(["divRef", divRef.current]);
    };

    const handleWindowResizeEvent = (): void => {
        window.requestAnimationFrame(() => {
            doSomethingWithRef();
        });
    };

    useEffect(
        () => {
        
            window.addEventListender("resize", handleWindowResizeEvent);
            
            // componentWillUnmount
            return (): void => {
                window.removeEventListender("resize", handleWindowResizeEvent);
            };
        
        },
        [] // componentDidMount
    };
    
    return <div ref={divRef}>Hello, World!</div>;

};
vladeck
  • 336
  • 3
  • 14

1 Answers1

1

Using the return statement of a useEffect hook is not equivalent to calling the class-based componentWillUnmount lifecycle method, as the cleanup is run after the component is unmounted, not before. This question discusses this issue in detail.

From what I can tell, it would be theoretically possible for your component to have unmounted, destroying the referenced element, before the event handler is removed. React could have behavior to prevent this, and regardless it would require extremely quick input by the user and seems to me pretty unlikely to be a problem. Any issue it might cause can be mitigated pretty easily by simply checking to make sure the ref exists, so I would just do a null check if you're concerned about it:

if (divRef.current) {
  doSomethingWithRef();
}
Chris B.
  • 5,477
  • 1
  • 12
  • 30
  • Thank you @chris-b, the link you provided served as both refresher and expander. I'll mark this as an answer. – vladeck Sep 27 '20 at 12:35