Guide complet sur le défilement infini en React

Le défilement infini est un modèle d’expérience utilisateur où du nouveau contenu se charge au fur et à mesure que les utilisateurs font défiler une page. Courant dans les fils d’actualités sociales, les chronologies et les applications d’information, c’est une façon fluide d’explorer de grands ensembles de données sans utiliser de boutons de pagination. Dans ce guide, vous apprendrez à créer un défilement infini en React en utilisant à la fois une bibliothèque tierce et un hook personnalisé.
Points clés
- Découvrez 2 méthodes pratiques pour implémenter le défilement infini en React
- Utilisez un hook personnalisé avec IntersectionObserver ou un package tiers
- Gérez les états de chargement, la pagination et les résultats vides
Qu’est-ce que le défilement infini ?
Le défilement infini charge de nouvelles données lorsque l’utilisateur s’approche de la fin d’une liste. Il élimine le besoin de pagination et crée une expérience de navigation continue. Vous le verrez dans des produits comme Instagram, Twitter et Reddit.
Méthode 1 : Utilisation d’un package (react-infinite-scroll-component
)
La façon la plus simple d’implémenter le défilement infini en React est d’utiliser un package bien testé.
Étape 1 : Installation
npm install react-infinite-scroll-component
Étape 2 : Exemple d’utilisation basique
import InfiniteScroll from 'react-infinite-scroll-component';
function Feed() {
const [items, setItems] = useState([]);
const [page, setPage] = useState(1);
const [hasMore, setHasMore] = useState(true);
const fetchMoreData = async () => {
const res = await fetch(`/api/posts?page=${page}`);
const newItems = await res.json();
if (newItems.length === 0) setHasMore(false);
else {
setItems(prev => [...prev, ...newItems]);
setPage(prev => prev + 1);
}
};
return (
<InfiniteScroll
dataLength={items.length}
next={fetchMoreData}
hasMore={hasMore}
loader={<h4>Loading...</h4>}
endMessage={<p>No more results</p>}
>
{items.map(item => <div key={item.id}>{item.title}</div>)}
</InfiniteScroll>
);
}
Avantages
- Rapide à mettre en place
- États de chargement et de fin intégrés
Inconvénients
- Moins de contrôle sur la logique de défilement
- Ajoute une dépendance de package
Méthode 2 : Hook personnalisé avec IntersectionObserver
Cette méthode vous donne un contrôle total sans dépendances supplémentaires.
Étape 1 : Créer un hook
function useInfiniteScroll(callback, ref) {
useEffect(() => {
const observer = new IntersectionObserver(([entry]) => {
if (entry.isIntersecting) callback();
});
if (ref.current) observer.observe(ref.current);
return () => observer.disconnect();
}, [callback, ref]);
}
Étape 2 : Utiliser dans un composant
function Feed() {
const [items, setItems] = useState([]);
const [page, setPage] = useState(1);
const [hasMore, setHasMore] = useState(true);
const sentinelRef = useRef(null);
const loadMore = async () => {
if (!hasMore) return;
const res = await fetch(`/api/posts?page=${page}`);
const newItems = await res.json();
if (newItems.length === 0) setHasMore(false);
else {
setItems(prev => [...prev, ...newItems]);
setPage(prev => prev + 1);
}
};
useInfiniteScroll(loadMore, sentinelRef);
return (
<div>
{items.map(item => <div key={item.id}>{item.title}</div>)}
<div ref={sentinelRef} style={{ height: 1 }} />
</div>
);
}
Avantages
- Entièrement personnalisable
- Fonctionne avec n’importe quelle logique de défilement ou API
Inconvénients
- Nécessite plus de configuration
- IntersectionObserver n’est pas pris en charge par IE11
Modèles et conseils pour le monde réel
- Débouncer les appels fetch pour éviter de surcharger les API
- Afficher un spinner ou un squelette de chargement pour une meilleure expérience utilisateur
- Ajouter une logique de nouvelle tentative pour les erreurs réseau
- Gérer les cas particuliers comme zéro résultat ou pages vides
if (items.length === 0 && !hasMore) {
return <p>No posts found.</p>;
}
Considérations de performance
- Utilisez des bibliothèques comme
react-window
pour la virtualisation lors du rendu de milliers d’éléments - Mémorisez les composants d’éléments pour éviter les re-rendus
- Nettoyez correctement les observateurs pour éviter les fuites de mémoire
useEffect(() => {
const observer = new IntersectionObserver(...);
return () => observer.disconnect();
}, []);
Conclusion
Le défilement infini est une fonctionnalité courante dans les interfaces modernes. Que vous préfériez la simplicité d’un package ou le contrôle d’un hook personnalisé, React rend les deux approches accessibles. Tenez toujours compte des performances et du retour d’information sur le chargement lors de l’implémentation du défilement infini.
FAQ
L'utilisation d'une bibliothèque comme `react-infinite-scroll-component` offre une configuration rapide et pratique.
Définissez un indicateur `hasMore` à false lorsque l'API renvoie un tableau vide.
Cela peut être le cas si vous affichez trop d'éléments. Utilisez des outils de virtualisation comme `react-window` pour gérer les grandes listes.
Utilisez `IntersectionObserver` pour déclencher le chargement de données lorsqu'une `div` en bas (sentinelle) devient visible.