import { useEffect, useRef, useState } from 'react' interface UseInfiniteScrollOptions { hasMore: boolean loading: boolean onLoadMore: () => void threshold?: number } export function useInfiniteScroll({ hasMore, loading, onLoadMore, threshold = 200, }: UseInfiniteScrollOptions): React.RefObject { const observerRef = useRef(null) const [isIntersecting, setIsIntersecting] = useState(false) useEffect(() => { if (!hasMore || loading) { return } const observer = new IntersectionObserver( (entries) => { const entry = entries[0] if (entry?.isIntersecting) { setIsIntersecting(true) } else { setIsIntersecting(false) } }, { rootMargin: `${threshold}px`, } ) const currentRef = observerRef.current if (currentRef) { observer.observe(currentRef) } return () => { if (currentRef) { observer.unobserve(currentRef) } } }, [hasMore, loading, threshold]) useEffect(() => { if (isIntersecting && hasMore && !loading) { onLoadMore() } }, [isIntersecting, hasMore, loading, onLoadMore]) return observerRef }