Blog>
Snippets

Implementing Infinite Scroll with Next.js and IntersectionObserver

Create a list that fetches and displays more items as the user scrolls, using IntersectionObserver for lazy loading.
import { useState, useEffect, useRef, useCallback } from 'react';
Import required hooks and useRef from React.
const useInfiniteScroll = (fetchMoreFunc) => {
  // Ref to track the DOM element
  const observerRef = useRef(null);

  const observer = new IntersectionObserver((entries) => {
    const firstEntry = entries[0];
    if (firstEntry.isIntersecting) {
      fetchMoreFunc(); // Call the function to fetch more items
    }
  }, {
    threshold: 1.0 // Trigger when 100% of the observed item is in view
  });

  useEffect(() => {
    const currentRef = observerRef.current;
    observer.observe(currentRef);

    return () => {
      observer.unobserve(currentRef);
    };
  }, []);

  return observerRef;
};
Creates a custom hook useInfiniteScroll which takes a fetchMoreFunc function. This hook initializes a IntersectionObserver to monitor the element for visibility. When the element comes fully into view, it calls fetchMoreFunc to load more items.
const InfiniteList = ({ fetchMore }) => {
  const [items, setItems] = useState([]);

  const loadMoreItems = async () => {
    const moreItems = await fetchMore();
    setItems(currentItems => [...currentItems, ...moreItems]);
  };

  const observerRef = useInfiniteScroll(loadMoreItems);

  // Initial fetch
  useEffect(() => {
    loadMoreItems();
  }, []);

  return (
    <div>
      {items.map((item, index) => (
        <div key={index}>{item}</div>
      ))}
      <div ref={observerRef}>Loading more...</div>
    </div>
  );
};
Implements the InfiniteList component which uses useInfiniteScroll hook by passing it the loadMoreItems function. This component handles the state of items and initial fetch of data rendering each item within a div. It also includes a Loading more... div that is monitored by the IntersectionObserver for triggering further data loads.
export default InfiniteList;
Exports the InfiniteList component to use in other parts of the application.