observer.unobserve() in useEffect cleanup throwing error that parameter is not of type Element
Asked Answered
S

1

5

Simple Component Example:

export default function App () {
  const videoRef = useRef();
  const onScreen = useOnScreen(videoRef, "-300px"); // hook for play/pause based on visibility
  
  <div ref={videoRef} className="h-72 my-4 rounded-2xl">
    <ReactPlayer
      url="my-recording.mov"
      loop
      playing={onScreen ? true : false}  />
  </div>
}

I am using the useOnScreen hook from here: https://usehooks.com/useOnScreen/

The hook works fine when running but when I change page by clicking a link using react-router-dom it throws the following error:

TypeError: Failed to execute 'unobserve' on 'IntersectionObserver': parameter 1 is not of type 'Element'.

I think the problem is in the cleanup of useEffect function (maybe the ref is already unmounted when cleanup starts to run therefore ref.current is null):

return () => {
  observer.unobserve(ref.current); // here ref.current might be null
};

It works properly if I add a check before calling unobserve:

return () => {
  if (ref.current) {
    observer.unobserve(ref.current);
  }
};

But I am not sure if this will leave the observer running and waste resources.

Please provide a solution that works and is also efficient.

Scoggins answered 27/6, 2021 at 15:49 Comment(0)
J
9

I have faced into the same issue but solved it by using useLayoutEffect instead of useEffect in the useOnScreen hook.

Jena answered 24/3, 2022 at 8:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.