new-personal-site/components/lib/hooks/useIntersectionObserver.tsx

67 lines
1.7 KiB
TypeScript
Raw Normal View History

2025-01-05 06:25:38 +00:00
import React from "react";
type Param = {
elementRef?: React.MutableRefObject<Element | undefined>;
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 };
}