import React from "react"; type Param = { elementRef?: React.MutableRefObject; className?: string; options?: IntersectionObserverInit; removeIntersected?: boolean; }; export default function useIntersectionObserver({ elementRef, className, options, removeIntersected, }: Param) { const [isIntersecting, setIsIntersecting] = React.useState(false); const [refresh, setRefresh] = React.useState(0); const observerCallback: IntersectionObserverCallback = React.useCallback( (entries, observer) => { const entry = entries[0]; if (entry.isIntersecting) { setIsIntersecting(true); if (removeIntersected) { observer.unobserve(entry.target); } } else { setIsIntersecting(false); } }, [] ); React.useEffect(() => { const element = elementRef?.current; const elements = className ? document.querySelectorAll(`.${className}`) : null; if (!element && !className && refresh < 5) { requestAnimationFrame(() => { setTimeout(() => { setRefresh(refresh + 1); }, 2000); }); return; } const observer = new IntersectionObserver(observerCallback, { rootMargin: "0px 0px 0px 0px", ...options, }); if (elements) { elements.forEach((el) => { observer.observe(el); }); } else if (element) { observer.observe(element); } }, [refresh]); return { isIntersecting }; }