Back to Dashboard
Machine CodingINTERMEDIATE

Implement an Infinite Scroll component with real-time data fetching.

ReactHooksAPIPerformance

Live Interactive Demo

Loading Demo...

Implementation

typescript.tsx
import React, { useEffect, useState, useRef, useCallback } from 'react';

const InfiniteScroll = () => {
  const [photos, setPhotos] = __PH_34__([]);
  const [loading, setLoading] = __PH_35__(false);
  const [page, setPage] = __PH_36__(1);
  const observer = __PH_37__();

  const lastElementRef = __PH_38__(node => {
    if (loading) return;
    if (observer.current) observer.current.disconnect();
    observer.current = new IntersectionObserver(entries => {
      if (entries[0].isIntersecting) {
        setPage(prev => prev + 1);
      }
    });
    if (node) observer.current.observe(node);
  }, [loading]);

  __PH_39__(() => {
    const fetchPhotos = async () => {
      setLoading(true);
      const res = await fetch(`https://picsum.photos/v2/list?page=${page}&limit=10`);
      const data = await res.json();
      setPhotos(prev => [...prev, ...data]);
      setLoading(false);
    };
    fetchPhotos();
  }, [page]);

  return (
    <div className='grid grid-cols-2 gap-4'>
      {photos.map((photo, i) => (
        <img 
          key={photo.id} 
          ref={i === photos.length - 1 ? lastElementRef : null}
          src={photo.download_url} 
          alt={photo.author} 
          className='rounded-lg w-full h-48 object-cover'
        />
      ))}
      {loading && <p>Loading...</p>}
    </div>
  );
};

The Core Concept

Infinite scrolling allows users to load content continuously as they scroll down the page, improving UX for large datasets. Key concepts include:

1. **Intersection Observer API**: more performant than scroll event listeners as it doesn&apos;t run on every pixel scroll. 2. **Loading States**: managing &apos;isLoading&apos; to prevent duplicate requests. 3. **Page Management**: tracking the current page index for the API. 4. **Cleanup**: ensuring observers are disconnected when the component unmounts.

In this implementation, we use `picsum.photos` to fetch images and a ref-based &apos;trigger&apos; element at the bottom of the list.