Maison > Article > interface Web > Construire un composant de défilement infini dans React
Nous voyons un défilement infini dans les applications et les pages Web, en particulier dans les médias sociaux, qui veulent simplement que nous fassions défiler. Bien que faire défiler sans réfléchir ne soit pas une bonne chose, créer votre propre défilement infini est génial. En tant que développeur, nous devrions essayer de recréer les composants que nous voyons en surfant sur le Web. Cela peut vous mettre au défi d'en savoir plus et de sortir des sentiers battus lors de la mise en œuvre de certains composants.
De plus, si vous souhaitez implémenter un défilement infini dans votre application, vous pouvez suivre le guide pour créer le vôtre. Vous pouvez ajouter votre propre code pour améliorer le comportement du défilement.
Dans cet article, nous allons créer un composant de défilement infini à partir de zéro. Il couvrira les sujets suivants :
Maintenant, commençons.
Nous allons utiliser CRA pour créer l'application React de base. Vous pouvez le faire en exécutant la commande suivante :
npx create-react-app infinite-scroll
Si vous souhaitez Vite ou NextJS, vous pouvez également le faire. Hormis des changements mineurs, les autres choses resteront les mêmes.
Remarque : Pour exécuter cette commande, vous devez avoir NodeJS préinstallé. Supprimez également certains codes passe-partout inutiles de l’ARC.
Nous allons avoir besoin d'une dépendance pour récupérer les données d'une API. Après avoir paramétré React, nous pouvons installer Axios avec la commande suivante :
npm install axios
Maintenant, nous sommes prêts à créer le composant.
Nous allons créer un composant qui va récupérer les données de films populaires à partir de l'API Tmdb. C'est gratuit, vous pouvez obtenir leur clé API sur leur site Web. Construisons d'abord l'endroit où ils récupèrent les données, puis ajoutons des fonctionnalités de défilement infinies.
Voici le code du composant App :
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 ( <div className="App"> <header className="App-header"> Popular movies according to Tmdb <div className="movieCardContainer"> {data.length > 1 && data.map((item) => { return ( <MovieCard key={item.id} title={item.original_title} description={item.overview} rating={item.vote_average} imageURL={item.poster_path} /> ); })} {loading && <h1>Loading....</h1>} </div> </header> </div> ); } export default App;
Vous pouvez à peu près comprendre le code, où nous récupérons les données et les transmettons au composant MovieCard en tant qu'accessoire.
Créez un composant MovieCard.js pour afficher les informations de chaque film.
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 ( <div className="movieCard"> <img src={imagePath} height={400} /> <div className="movieInfo"> <h3>{title}</h3> <p>{description}</p> <p>{rating.toFixed(1)}⭐</p> </div> </div> ); };
Voici le CSS de l'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; }
Maintenant, commençons par comprendre comment nous allons construire le parchemin infini. Pour cela, nous allons regarder la position de la barre de défilement. Lorsque la position de la barre de défilement est juste au-dessus de la fin de la page, nous allons définir l'état de chargement sur true.
Nous allons avoir un autre useEffect qui va incrémenter l'état de la page de 1. Une fois le numéro de page mis à jour, le useEffect initial qui a la page comme dépendance se déclenchera. Cela invoquera la fonction fetchMovie() pour récupérer les données.
Tout d'abord, nous allons ajouter même l'écoute pour savoir quand la position de la barre de défilement est modifiée.
window.addEventListener("scroll", handleScroll);
Lorsque le défilement se produit, nous allons vérifier si la position actuelle de la barre de défilement est juste au-dessus du bas de la page Web (c'est-à-dire la zone de défilement verticale totale). Si oui, nous changeons l'état de chargement en vrai.
const handleScroll = () => { if (document.body.scrollHeight - 300 < window.scrollY + window.innerHeight) { setLoading(true); } };
Après avoir réussi à changer l'état de chargement, nous pouvons implémenter un useEffect pour incrémenter le numéro de page. Ainsi, la récupération des données du film peut avoir lieu.
useEffect(() => { if (loading == true) { setPage((prevPage) => prevPage + 1); } }, [loading]); // other useEffect that we already implemented useEffect(() => { fetchMovie(); }, [page]);
Étant donné que le défilement peut déclencher handleScroll plusieurs fois pendant le défilement, cela entraînera un appel inutile de la fonction plusieurs fois. Nous pouvons ajouter un anti-rebond à la fonction afin que cela puisse prendre un certain temps avant d'invoquer la fonction.
// 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));
Voici le code complet de l'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 ( <div className="App"> <header className="App-header"> Popular movies according to Tmdb <div className="movieCardContainer"> {data.length > 1 && data.map((item) => { return ( <MovieCard key={item.id} title={item.original_title} description={item.overview} rating={item.vote_average} imageURL={item.poster_path} /> ); })} {loading && <h1>Loading....</h1>} </div> </header> </div> ); } export default App;
Voici le GIF démontrant le fonctionnement de l'application.
Construire un composant de défilement infini dans React peut être une expérience très enrichissante. Il améliore non seulement votre compréhension du fonctionnement du défilement, mais vous apprend également la gestion de l'état, les écouteurs d'événements et les techniques d'optimisation telles que l'anti-rebond. En suivant ce guide, vous disposez désormais d'une configuration de base de défilement infini que vous pouvez personnaliser et améliorer en fonction de vos besoins.
Que vous affichiez des données de films, des articles de blog ou tout autre contenu, ce composant constitue une base solide. N'oubliez pas que la clé est de garantir une expérience utilisateur fluide en gérant soigneusement quand et comment les données sont récupérées lorsque l'utilisateur fait défiler. Bon codage !
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!