typescriptintermediate
Infinite Scroll Hook v2
Intersection Observer-based infinite scroll with loading, error, and hasMore states.
typescriptPress ⌘/Ctrl + Shift + C to copy
import { useState, useEffect, useRef, useCallback } from 'react';
interface UseInfiniteScrollOptions<T> {
fetchFn: (page: number) => Promise<T[]>;
pageSize?: number;
}
export function useInfiniteScroll<T>({ fetchFn, pageSize = 20 }: UseInfiniteScrollOptions<T>) {
const [items, setItems] = useState<T[]>([]);
const [page, setPage] = useState(1);
const [loading, setLoading] = useState(false);
const [hasMore, setHasMore] = useState(true);
const observerRef = useRef<IntersectionObserver>();
const loadMore = useCallback(async () => {
if (loading || !hasMore) return;
setLoading(true);
try {
const newItems = await fetchFn(page);
setItems(prev => [...prev, ...newItems]);
setHasMore(newItems.length === pageSize);
setPage(p => p + 1);
} finally {
setLoading(false);
}
}, [page, loading, hasMore, fetchFn, pageSize]);
const sentinelRef = useCallback((node: HTMLElement | null) => {
if (observerRef.current) observerRef.current.disconnect();
observerRef.current = new IntersectionObserver(entries => {
if (entries[0].isIntersecting) loadMore();
});
if (node) observerRef.current.observe(node);
}, [loadMore]);
return { items, loading, hasMore, sentinelRef };
}Use Cases
- Feed-style content
- Search results pagination
Tags
Related Snippets
Similar patterns you can reuse in the same workflow.
typescriptadvanced
useInfiniteQuery Hook
Implement infinite scrolling with cursor-based pagination, loading states, and intersection observer.
Best for: Infinite scroll feeds
#react#hooks
typescriptintermediate
Infinite Scroll with Intersection Observer
Load more items as the user scrolls using IntersectionObserver. No external libraries required.
Best for: Feed pagination
#infinite-scroll#intersection-observer
typescriptadvanced
useMutationObserver Hook
Wraps the MutationObserver API in a React hook to observe DOM changes on a target element.
Best for: Third-party widget monitoring
#hooks#dom
typescriptintermediate
useResizeObserver Hook
Tracks element dimensions using ResizeObserver with debounced updates.
Best for: Responsive layouts
#hooks#resize