Maison  >  Article  >  interface Web  >  Maîtrisez le défilement infini en quelques étapes faciles

Maîtrisez le défilement infini en quelques étapes faciles

WBOY
WBOYoriginal
2024-08-18 07:04:351058parcourir

Master Infinite Scrolling in Easy Steps

Défilement infini

Nous pouvons implémenter un défilement infini en utilisant l'API IntersectionObserver fournie par le navigateur.
Pour mettre en œuvre nous pouvons simplement suivre ces étapes :-

  1. Nous pouvons utiliser une API fictive pour notre défilement infini, puis créer un hook personnalisé
  2. Ce hook personnalisé prend les paramètres de l'API comme son propre paramètre de fonction.
  3. Ensuite, nous pouvons implémenter simplement l'appel API, en utilisant useEffect et axios, en passant les paramètres des paramètres fonctionnels.
  4. Nous pouvons avoir le chargement, l'erreur, hasMore et les données comme état
  5. Nous pouvons alors également utiliser setTimeout pour pouvoir vérifier correctement le chargement ainsi que le défilement infini
  6. hasMore sera équivalent à la longueur du tableau de données que nous affichons actuellement dans la page par rapport à ce que nous obtenons de l'appel API
  7. Ce hasmore est là pour éviter les appels même lorsque nous avons atteint la fin de nos données.
  8. Une fois le hook personnalisé présent dans notre page principale, nous créerons l'état des paramètres que nous transmettions
  9. Ensuite, nous transmettrons les paramètres à nos hooks personnalisés et récupérerons les données
  10. La liste des données que nous obtenons, nous la restituerons à l'aide d'une carte, puis l'afficherons
  11. Maintenant, nous devons appliquer le défilement infini une fois que nous atteignons la fin, donc pour les dernières données d'élément du tableau que nous recevons, nous ajouterons simplement une référence
  12. Cette référence sera équivalente à une fonction useCallback, dont le paramètre sera ce dernier élément.
  13. Ensuite nous allons créer un useRef dont la valeur sera par défaut nulle
  14. Maintenant, nous allons vérifier si nous sommes en état de chargement ou non. Si oui, nous reviendrons simplement
  15. Ensuite, nous vérifierons si cette valeur actuelle de useRef est nulle ou non. S'il n'est pas nul, nous déconnecterons simplement cet observateur. L'idée ici étant que l'observateur doit être nouveau à chaque fois, puisqu'à chaque fois nous aurons de nouvelles données
  16. Nous allons maintenant attribuer cette nouvelle valeur observer.current de la fonction de rappel par le nouveau IntersectionObserver. L'API IntersectionObserver renverra une fonction de rappel, avec des entrées comme paramètre.
  17. Ces entrées sont essentiellement la valeur de notre dernier élément lorsqu'il se trouve dans la page. Nous voulons la condition dans laquelle nous interagirons avec ces entrées dans la page
  18. Nous avons donc une valeur booléenne pour chaque entrée. estIntersecting
  19. Quand cela est vrai, nous modifierons les paramètres du hook personnalisé. Cela appellera à nouveau l'API et restituera également à nouveau
  20. Enfin, nous devons observer l'élément que nous avons passé en rappel, donc si nous avons l'élément, nous l'observerons simplement.

Code

CustomHook.jsx

import axios from "axios";
import { useEffect, useState } from "react";
import { API_URL } from "../common/constants";

export const useAuthorList = (limit, page) => {
  const [isLoading, setIsLoading] = useState(false);
  const [authorList, setAuthorList] = useState([]);
  const [error, setError] = useState("");
  const [hasMore, setHasMore] = useState(true);

  useEffect(() => {
    setIsLoading(true);
    setTimeout(() => {
      axios({
        method: "GET",
        url: API_URL,
        params: { limit: limit, page: page },
      })
        .then((res) => {
          setAuthorList(res.data.data);
          setHasMore(res.data.data.length === limit);
          setIsLoading(false);
        })
        .catch((e) => setError(e));
    }, 500);
  }, [limit, page]);

  return [isLoading, authorList, error, hasMore];
};

App.jsx

import React, { useCallback, useRef, useState } from "react";
import { useAuthorList } from "./hooks/useAuthorList";
import { AuthorQuotes } from "./components/AuthorQuotes";

const App = () => {
  const [limit, setLimit] = useState(10);
  const [page, setPage] = useState(1);
  const [isLoading, authorList, error, hasMore] = useAuthorList(limit, page);

  const observer = useRef(null);
  const infiniteReference = useCallback(
    (element) => {
      if (isLoading) return;
      if (observer.current) {
        observer.current.disconnect();
      }

      observer.current = new IntersectionObserver((entries) => {
        if (entries[0].isIntersecting && hasMore) {
          setLimit((prev) => prev + 10);
        }
      });

      if (element) {
        observer.current.observe(element);
      }
    },
    [isLoading, hasMore]
  );

  return (
    <div className="author-quotes-list">
      {authorList.length > 0 &&
        authorList.map((authorQuotes, index) => {
          if (index + 1 === authorList.length) {
            return (
              <AuthorQuotes
                authorQuotes={authorQuotes}
                hasReference
                infiniteReference={infiniteReference}
              />
            );
          }
          return <AuthorQuotes authorQuotes={authorQuotes} />;
        })}
      {isLoading && <>Loading...</>}
    </div>
  );
};

export default App;

constantes.js

export const API_URL = "https://api.javascripttutorial.net/v1/quotes/"

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!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn