From 093855024ea2d148b354ebfb8a43c639dd522eac Mon Sep 17 00:00:00 2001 From: Roderick Hsiao Date: Fri, 20 Sep 2024 12:35:09 -0700 Subject: [PATCH] fix: observer high level DOM for changes --- package.json | 2 +- src/lib/useInViewport.tsx | 25 ++++++++++++++++--------- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index 2d3dbb0..312a05b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-in-viewport", - "version": "1.0.0-beta.5", + "version": "1.0.0-beta.6", "description": "Track React component in viewport using Intersection Observer API", "author": "Roderick Hsiao ", "license": "MIT", diff --git a/src/lib/useInViewport.tsx b/src/lib/useInViewport.tsx index 0b03378..d34a72a 100644 --- a/src/lib/useInViewport.tsx +++ b/src/lib/useInViewport.tsx @@ -30,6 +30,8 @@ const useInViewport = ( const enterCountRef = useRef(0); const leaveCountRef = useRef(0); + // State to track when target is available + const [isTargetReady, setIsTargetReady] = useState(Boolean(target.current)); function startObserver({ observerRef }) { const targetRef = target.current; @@ -109,23 +111,28 @@ const useInViewport = ( }; }, [target.current, options, config, onEnterViewport, onLeaveViewport]); - // handles when ref changes + // Use MutationObserver to detect when `target.current` becomes non-null + // only at start up useEffect(() => { const currentElement = target.current; - const observerRef = observer.current; + let mutationObserver: MutationObserver | null = null; + // MutationObserver callback to check when the target ref is assigned const handleOnChange = () => { - startObserver({ - observerRef, - }); + if (target.current && !isTargetReady) { + setIsTargetReady(true); + if (mutationObserver) { + mutationObserver.disconnect(); + } + } }; - let mutationObserver: MutationObserver; if (currentElement) { + setIsTargetReady(true); // If target is already available, mark it ready + } else { + // Observe changes to detect when `target.current` becomes non-null mutationObserver = new MutationObserver(handleOnChange); - - // Start observing the DOM element for mutations - mutationObserver.observe(currentElement, defaultMutationObserverOption); + mutationObserver.observe(document.body, defaultMutationObserverOption); } // Cleanup function to stop observing when the component unmounts