A performant React hook for infinite scrolling using Intersection Observer API
npm install react-scroll-infinityA performant React hook for infinite scrolling using the Intersection Observer API.
Created by Sayed Abdul Karim


š Live Demo | š® Playground
- Performant - Uses Intersection Observer (no scroll event listeners)
- Lightweight - ~1KB minified
- TypeScript - Full type support
- Configurable - Customize threshold and root margin
- Zero dependencies - Only requires React as peer dependency
``bash`
npm install react-scroll-infinity
`bash`
yarn add react-scroll-infinity
`bash`
pnpm add react-scroll-infinity
`tsx
import { useInfiniteScroll } from 'react-scroll-infinity';
function PostList() {
const [posts, setPosts] = useState([]);
const [page, setPage] = useState(1);
const [hasMore, setHasMore] = useState(true);
const loadMore = async () => {
const newPosts = await fetchPosts(page);
setPosts(prev => [...prev, ...newPosts]);
setHasMore(newPosts.length > 0);
setPage(prev => prev + 1);
};
const { sentinelRef, isLoading, error } = useInfiniteScroll({
loadMore,
hasMore,
});
return (
{/ Sentinel element - triggers loading when visible /}
API
$3
#### Options
| Option | Type | Default | Description |
|--------|------|---------|-------------|
|
loadMore | () => Promise | required | Function to load more data |
| hasMore | boolean | required | Whether more data is available |
| threshold | number | 0.1 | Intersection Observer threshold (0-1) |
| rootMargin | string | '100px' | Margin around the root |#### Returns
| Property | Type | Description |
|----------|------|-------------|
|
sentinelRef | RefObject | Ref to attach to sentinel element |
| isLoading | boolean | Loading state |
| error | Error \| null | Error state |Advanced Usage
$3
`tsx
const { sentinelRef, isLoading } = useInfiniteScroll({
loadMore,
hasMore,
threshold: 0.5, // Trigger when 50% visible
rootMargin: '200px', // Start loading 200px before visible
});
`$3
The hook works with both window scroll and container scroll. Just place the sentinel element inside your scrollable container.
`tsx
{items.map(item => )}
`TypeScript
Full TypeScript support with exported types:
`tsx
import {
useInfiniteScroll,
UseInfiniteScrollOptions,
UseInfiniteScrollReturn
} from 'react-scroll-infinity';
``Works in all browsers that support Intersection Observer API (95%+ global support).
Sayed Abdul Karim
- GitHub: @sayedabdulkarim
MIT