Skip to content

Instantly share code, notes, and snippets.

@leodutra
Last active October 23, 2024 19:15
Show Gist options
  • Save leodutra/f585e86d218ac009686fa228fdfacfb0 to your computer and use it in GitHub Desktop.
Save leodutra/f585e86d218ac009686fa228fdfacfb0 to your computer and use it in GitHub Desktop.
useIntersectionObserver - use intersection observer
import { type RefObject, useEffect, useState } from 'react';
export type IntersectionObserverOptions = IntersectionObserverInit & {
intersectOnce?: boolean;
skip?: boolean;
};
const emptyOptions: IntersectionObserverInit = {};
const useIntersectionObserver = (
ref: RefObject<Element>,
{
intersectOnce = false,
skip = false,
...options
}: IntersectionObserverOptions = emptyOptions
): boolean => {
const [isIntersecting, setIntersecting] = useState<boolean>(false);
if (isIntersecting && intersectOnce) {
skip = true;
}
const stringifiedOptions = skip ? '{}' : JSON.stringify(options);
const observerEffect = () => {
if (skip) {
return;
}
const currentElement = ref.current;
if (!currentElement) {
return;
}
const observer = new IntersectionObserver(([entry]) => {
if (entry.isIntersecting) {
setIntersecting(true);
if (intersectOnce) {
observer.unobserve(currentElement);
}
} else {
setIntersecting(false);
}
}, options);
observer.observe(currentElement);
return () => {
observer.unobserve(currentElement);
};
};
useEffect(observerEffect, [
skip,
ref.current,
stringifiedOptions,
intersectOnce,
]);
return isIntersecting;
};
export default useIntersectionObserver;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment