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! 🎉