Cover image for Building an Infinite Scroll Component in React

Building an Infinite Scroll Component in React

Suraj Vishwakarma

25 Mar, 2025


Introduction

Infinite scrolling is a common feature in modern applications, especially social media platforms that encourage continuous engagement. While excessive scrolling isn't always beneficial, building an infinite scroll component from scratch is a great learning experience for developers.

In this guide, you'll learn how to implement an optimized infinite scroll in React. This tutorial covers:

Let's get started!

Environment Setup

We will use Create React App (CRA) to set up the project. Run the following command:

    npx create-react-app infinite-scroll

Alternatively, you can use Vite or Next.js with minimal modifications.

Note: Ensure Node.js is installed before running the command. Also, clean up the CRA boilerplate code.

Next, install Axios to fetch data from an API:

    npm install axios

Now, let's build the component.

App Component

We'll fetch popular movie data from TMDB API. Obtain a free API key from their website.

App.js

import "./App.css";
import { useState, useEffect } from "react";
import axios from "axios";
import { MovieCard } from "./MovieCard";

function App() {
  const [page, setPage] = useState(1);
  const [data, setData] = useState([]);
  const [loading, setLoading] = useState(false);

  const fetchMovie = async () => {
    const URL = `https://api.themoviedb.org/3/movie/popular?language=en-US&page=${page}`;
    const response = await axios.get(URL, {
      headers: {
        Authorization: "Bearer YOUR_API_KEY",
        Accept: "application/json",
      },
    });
    setData((prevData) => [...prevData, ...response.data.results]);
    setLoading(false);
  };

  useEffect(() => {
    fetchMovie();
  }, [page]);

  return (
    <div className="App">
      <header className="App-header">
        <h1>Popular Movies from TMDB</h1>
        <div className="movieCardContainer">
          {data.map((item) => (
            <MovieCard
              key={item.id}
              title={item.original_title}
              description={item.overview}
              rating={item.vote_average}
              imageURL={item.poster_path}
            />
          ))}
          {loading && <h2>Loading...</h2>}
        </div>
      </header>
    </div>
  );
}

export default App;

MovieCard.js

import React from "react";

export const MovieCard = ({ title, description, imageURL, rating }) => {
  const imagePath = `https://image.tmdb.org/t/p/w500${imageURL}`;
  return (
    <div className="movieCard">
      <img src={imagePath} height={400} alt={title} />
      <div className="movieInfo">
        <h3>{title}</h3>
        <p>{description}</p>
        <p>{rating.toFixed(1)}⭐</p>
      </div>
    </div>
  );
};

Infinite Scroll Implementation

To achieve infinite scrolling, we'll monitor the scrollbar position and trigger data fetching when reaching the bottom.

Detecting Scroll Position

const handleScroll = () => {
  if (document.documentElement.scrollHeight - 300 < window.scrollY + window.innerHeight) {
    setLoading(true);
  }
};

useEffect(() => {
  if (loading) setPage((prevPage) => prevPage + 1);
}, [loading]);

Optimizing Performance with Debounce

To prevent excessive function calls, we'll debounce the scroll event:

const debounce = (func, delay) => {
  let timeoutId;
  return (...args) => {
    if (timeoutId) clearTimeout(timeoutId);
    timeoutId = setTimeout(() => func(...args), delay);
  };
};

window.addEventListener("scroll", debounce(handleScroll, 500));

Final Thoughts

Building an infinite scroll component enhances your understanding of state management, event listeners, and performance optimization. With this implementation, you can further customize the scroll behavior to suit your needs.

Let's Connect 🚀

Happy coding! 🎉

Infinite Scroll Demo


Build by Suraj Vishwakarma.