diff --git a/packages/@mantine/hooks/src/use-in-viewport/use-in-viewport.ts b/packages/@mantine/hooks/src/use-in-viewport/use-in-viewport.ts index 79ad21fe986..3eddd966521 100644 --- a/packages/@mantine/hooks/src/use-in-viewport/use-in-viewport.ts +++ b/packages/@mantine/hooks/src/use-in-viewport/use-in-viewport.ts @@ -1,22 +1,25 @@ -import { useEffect, useMemo, useRef, useState } from 'react'; +import { useCallback, useRef, useState } from 'react'; -export function useInViewport() { - const ref = useRef(null); +export function useInViewport() { + const observer = useRef(null); const [inViewport, setInViewport] = useState(false); - const observer = useMemo(() => { - if (typeof IntersectionObserver === 'undefined') { - return null; - } - return new IntersectionObserver(([entry]) => setInViewport(entry.isIntersecting)); - }, [ref]); + const ref = useCallback((node: T | null) => { + if (typeof IntersectionObserver !== 'undefined') { + if (node && !observer.current) { + observer.current = new IntersectionObserver(([entry]) => + setInViewport(entry.isIntersecting) + ); + } else { + observer.current?.disconnect(); + } - useEffect(() => { - if (ref.current && observer) { - observer.observe(ref.current); - return () => observer.disconnect(); + if (node) { + observer.current?.observe(node); + } else { + setInViewport(false); + } } - return () => null; }, []); return { ref, inViewport };