Building an Infinite Scroll Component in React

Cover image for Building an Infinite Scroll Component in React

Building an Infinite Scroll Component in React

reacttutorial
Suraj Vishwakarma

Suraj Vishwakarma

Updated

Originally Published


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:

  • Setting up the environment
  • Building the infinite scroll component
  • Styling with CSS
  • Optimizing scroll performance

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

Suraj Vishwakarma

Suraj Vishwakarma

Frontend Developer

Open for Opportunities ๐Ÿš€

Specializing in performance-first React/Next.js experiences. Currently focused on SEO/AEO and seeking Frontend or DevRel challenges.