Building an Infinite Scroll Component in React

WBOY
Release: 2024-08-26 21:45:02
Original
956 people have browsed it

Introduction

We see infinite scrolling in applications and web pages especially social media that want us just to scroll. While mindlessly scrolling is not good, building your own infinite scroll is awesome. As a developer, we should try to recreate components that we see while surfing the web. It can challenge you to learn more and think out of the box when implementing some components.

Also, If you are looking to implement an infinite scroll in your application then you can follow the guide to create your own. You can add your own code to this improve the behaviour of the scroll.

In this article, we are going to build an infinite scroll component from scratch. It will cover the following topics:

  • Environment Setup
  • Building the Component
  • Adding CSS
  • Optimizing the Infinite Scroll

Now, let’s get started.

Environment Setup

We are going to use CRA to create the basic React application. You can do that my running the following command:

npx create-react-app infinite-scroll
Copy after login

If you wish to Vite or NextJS then you can also. Apart from minor changes other things will remain the same.

Note: To run this command, you need to have NodeJS pre-installed. Also, remove some of the unnecessary boilerplate code from CRA.

We are going to need one dependency to fetch data from an API. After setting React, we can install Axios with the following command:

npm install axios
Copy after login

Now, we are ready to create the component.

App Component

We are going to build an component that is going to fetch popular movie data from Tmdb API. It’s free you can get their API key from their website. Let’s build first where they are fetching the data and then add infinite scrolling features.

Here is the code for the App Component:

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); // for number of page in tmdb const [data, setData] = useState([]); // storing the fetched data const [loading, setLoading] = useState(false); // for setting loading state // fetching and stroring the data in the state const fetchMovie = async () => { const URL = `https://api.themoviedb.org/3/movie/popular?language=en-US&page=${page}`; const data = await axios.get(URL, { headers: { Authorization: "Bearer API KEY", Accept: "application/json", }, }); setData((prevData) => [...prevData, ...data.data.results]); // we are going to add the new data to current data. setLoading(false); }; // useEffecte for invoking the function at the start useEffect(() => { fetchMovie(); }, [page]); return ( 
Popular movies according to Tmdb
{data.length > 1 && data.map((item) => { return ( ); })} {loading &&

Loading....

}
); } export default App;
Copy after login

You can pretty much understand the code, where we are fetching the data and passing it into the MovieCard component as a prop.

Create a MovieCard.js component for displaying each movie's info.

MoveCard.js

import React from "react"; export const MovieCard = ({ title, description, imageURL, rating }) => { const imagePath = `https://image.tmdb.org/t/p/w500${imageURL}`; // poster image path URL return ( 

{title}

{description}

{rating.toFixed(1)}⭐

); };
Copy after login

Here is the CSS of the application:

App.css

.App { text-align: center; } .App-header { background-color: #282c34; min-height: 100vh; display: flex; flex-direction: column; align-items: center; padding-top: 1em; font-size: calc(10px + 2vmin); color: white; } .movieCardContainer{ margin-top: 1em; display: flex; flex-direction: column; gap: 1em; width: 60%; max-width: 800px; } .movieCard{ display: flex; } .movieInfo{ margin-left: 1em; text-align: left; } p{ font-size: 18px; }
Copy after login

Infinite Scroll

Now, let’s first, understand how we are going to build the infinite scroll. For this, we are going to look at the scroll bar position. When the scroll bar position is just above the end of the page, we are going to set the loading state to true.

We are going to have another useEffect that is going to increment the page state by 1. Once the page number is updated, the initial useEffect that has the page as a dependency will trigger. This will invoke the fetchMovie() function to fetch the data.

Adding EventListner to Scroll

First, we are going to add even listen to know when the scroll bar position is changed.

window.addEventListener("scroll", handleScroll);
Copy after login

handleScroll

When the scroll happens, we are going to check whether the current position of scoll bar is just above the bottom of the web page(ie total vertical scrollable area). If yes then we are changing the state of loading to true.

const handleScroll = () => { if (document.body.scrollHeight - 300 < window.scrollY + window.innerHeight) { setLoading(true); } };
Copy after login
  • scrollHeight : It is the property that returns the total height of the content, including the portion that is not visible on the screen. So, it will be the total scrollable area.
  • scrollY: It is the property that returns the number of pixels that the document has been scrolled vertically from the top. So it will be the area that has been scrolled.
  • innerHeight: It is the property that return the height of the browser’s Windows content area. It will be the scrollbar width. It is added to scrollY so that fetch happens when we reached the content rather than when we passed the content. ## useEffect

After successfully changing state of loading, we can implement a useEffect to incrementing the page number. So that, the fetching of the movie data can happen.

useEffect(() => { if (loading == true) { setPage((prevPage) => prevPage + 1); } }, [loading]); // other useEffect that we already implemented useEffect(() => { fetchMovie(); }, [page]);
Copy after login

Optimizing the eventListner

Since scroll can trigger handleScroll multiple times while scrolling, it will cause unnecessary invocation of the function multiple times. We can add debounce to the function so that it can take some time before invoking the function.

// debounce function function debounce(func, delay) { let timeoutId; return function (...args) { if (timeoutId) { clearTimeout(timeoutId); } timeoutId = setTimeout(() => { func(...args); }, delay); }; } // adding debounce to the eventListner window.addEventListener("scroll", debounce(handleScroll, 500));
Copy after login

Here is the complete code of the 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 data = await axios.get(URL, { headers: { Authorization: "Bearer API KEY", Accept: "application/json", }, }); setData((prevData) => [...prevData, ...data.data.results]); setLoading(false); }; useEffect(() => { fetchMovie(); }, [page]); const handleScroll = () => { if ( document.body.scrollHeight - 300 < window.scrollY + window.innerHeight ) { setLoading(true); } }; function debounce(func, delay) { let timeoutId; return function (...args) { if (timeoutId) { clearTimeout(timeoutId); } timeoutId = setTimeout(() => { func(...args); }, delay); }; } window.addEventListener("scroll", debounce(handleScroll, 500)); useEffect(() => { if (loading == true) { setPage((prevPage) => prevPage + 1); } }, [loading]); return ( 
Popular movies according to Tmdb
{data.length > 1 && data.map((item) => { return ( ); })} {loading &&

Loading....

}
); } export default App;
Copy after login

Here is the GIF demonstrating the workings of the application.

Building an Infinite Scroll Component in React

結論

React で無限スクロール コンポーネントを構築することは、非常にやりがいのある経験となる可能性があります。スクロールの仕組みについての理解が深まるだけでなく、状態管理、イベント リスナー、デバウンスなどの最適化テクニックについても学習できます。このガイドに従うことで、ニーズに応じてカスタマイズおよび改善できる基本的な無限スクロールのセットアップが完了しました。

映画データ、ブログ投稿、その他のコンテンツを表示する場合でも、このコンポーネントは強力な基盤として機能します。重要なのは、ユーザーがスクロールするときにデータがいつどのようにフェッチされるかを注意深く管理することで、スムーズなユーザー エクスペリエンスを確保することであることに注意してください。コーディングを楽しんでください!

The above is the detailed content of Building an Infinite Scroll Component in React. For more information, please follow other related articles on the PHP Chinese website!

source:dev.to
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!