Simple Infinite Scroll in React - A Beginner's Guide

What is Infinite Scroll?

Infinite scroll is a web design technique where content is continuously loaded as the user scrolls down the page. It's commonly used in social media feeds, search results, and product listings.

Interactive Demo & Code

Below you'll find a working demo of infinite scroll. Toggle between the demo and the complete source code to see how it works. Try scrolling to the bottom in the demo to see more items load automatically:

Interactive Demo

Demo Item 0

This is a demo item 0 for the infinite scroll tutorial

Demo Item 1

This is a demo item 1 for the infinite scroll tutorial

Demo Item 2

This is a demo item 2 for the infinite scroll tutorial

Demo Item 3

This is a demo item 3 for the infinite scroll tutorial

Demo Item 4

This is a demo item 4 for the infinite scroll tutorial

Demo Item 5

This is a demo item 5 for the infinite scroll tutorial

Demo Item 6

This is a demo item 6 for the infinite scroll tutorial

Demo Item 7

This is a demo item 7 for the infinite scroll tutorial

Demo Item 8

This is a demo item 8 for the infinite scroll tutorial

Demo Item 9

This is a demo item 9 for the infinite scroll tutorial

Scroll down for more items

How It Works

Let's break down the key parts of the implementation:

1. Setting Up the State

First, we need to set up our component's state to manage our items and loading state:

const [items, setItems] = useState(() => generateItems(0, 10));
const [loading, setLoading] = useState(false);
const loaderRef = useRef<HTMLDivElement>(null);

2. Creating the Intersection Observer

The Intersection Observer API helps us detect when the user has scrolled to the bottom. We set it up in a useEffect hook:

useEffect(() => {
  const observer = new IntersectionObserver(
    (entries) => {
      const firstEntry = entries[0];
      if (firstEntry.isIntersecting && !loading) {
        loadMore();
      }
    },
    { threshold: 0.5 }
  );

  if (loaderRef.current) {
    observer.observe(loaderRef.current);
  }

  return () => observer.disconnect();
}, [loading]);

Key Concepts

  • Intersection Observer: A browser API that tells us when an element becomes visible in the viewport
  • useRef: Used to maintain a reference to the loader element
  • useState: Manages our list of items and loading state
  • useEffect: Sets up and cleans up the observer

Making It Production-Ready

To make this implementation production-ready, consider adding:

  • Error handling for failed API requests
  • A loading skeleton or placeholder while items load
  • Debouncing to prevent too many API calls
  • Virtual scrolling for very large lists
  • End of content detection

Example with Error Handling

Here's how you might add error handling to the implementation:

const [error, setError] = useState<Error | null>(null);

const loadMore = async () => {
  if (loading) return;
  
  setLoading(true);
  setError(null);
  
  try {
    const response = await fetch(`/api/items?page=${page}`);
    if (!response.ok) {
      throw new Error('Failed to fetch items');
    }
    
    const newItems = await response.json();
    setItems(prev => [...prev, ...newItems]);
  } catch (err) {
    setError(err instanceof Error ? err : new Error('Failed to load items'));
  } finally {
    setLoading(false);
  }
};

Conclusion

You now have a basic understanding of how to implement infinite scroll in React! This implementation is:

  • Easy to understand and modify
  • Performant using Intersection Observer
  • Suitable for most basic use cases

Remember to adapt the code based on your specific needs and add appropriate error handling and loading states for a better user experience.