Files
cinny/src/app/hooks/useNearViewport.ts
T

31 lines
843 B
TypeScript
Raw Normal View History

import { RefObject, useEffect, useState } from 'react';
/**
* Returns true once the observed element has come within `margin` pixels of
* the viewport. Disconnects the observer after the first intersection so there
* is no ongoing overhead.
*/
export function useNearViewport(ref: RefObject<Element | null>, margin = 200): boolean {
const [triggered, setTriggered] = useState(false);
useEffect(() => {
const el = ref.current;
if (!el || triggered) return undefined;
const observer = new IntersectionObserver(
(entries) => {
if (entries[0]?.isIntersecting) {
setTriggered(true);
observer.disconnect();
}
},
{ rootMargin: `${margin}px` },
);
observer.observe(el);
return () => observer.disconnect();
}, [ref, margin, triggered]);
return triggered;
}