簡単なステップで無限スクロールをマスターする

WBOY
リリース: 2024-08-18 07:04:35
オリジナル
1111 人が閲覧しました

Master Infinite Scrolling in Easy Steps

無限スクロール

ブラウザが提供する IntersectionObserver API を使用して無限スクロールを実装できます。
実装するには、次の手順に従うだけです:-

  1. 無限スクロールにモック API を使用して、カスタム フックを作成できます
  2. このカスタム フックは、API のパラメーターを関数の独自のパラメーターとして受け取ります。
  3. その後、useEffect と axios を使用して、関数パラメータからパラメータを渡して API 呼び出しを実装するだけです。
  4. ロード、エラー、hasMore、データを状態として持つことができます
  5. その後、setTimeout を使用して、読み込みと無限スクロールを適切にチェックすることもできます
  6. hasMore は、API 呼び出しから取得したものと比較して、現在ページに表示しているデータの配列の長さに相当します
  7. これは、データの終わりに達した場合でも呼び出しを回避するためにあります。
  8. メイン ページにカスタム フックが存在したら、渡したパラメータの状態を作成します
  9. 次に、パラメータをカスタムフックに渡し、データを取得します
  10. 取得したデータのリストをマップを使用してレンダリングして表示します
  11. 最後に到達したら無限スクロールを適用する必要があるため、受信した配列の最後の要素データに対して単純に ref を追加します
  12. この ref は useCallback 関数と同等になり、そのパラメータはこの最後の要素になります。
  13. 次に、値がデフォルトで null になる useRef を作成します
  14. 次に、ロード状態かどうかを確認します。 「はい」の場合は、単純に返します
  15. 次に、この useRef の現在の値が null かどうかを確認します。 null でない場合は、単にこのオブザーバーを切断します。ここでの考え方は、毎回新しいデータが得られるため、オブザーバーは毎回新しい必要があるということです
  16. ここで、新しい IntersectionObserver によってコールバック関数のこの新しい observer.current 値を割り当てます。IntersectionObserver API は、パラメーターとしてエントリを含むコールバック関数を返します。
  17. これらのエントリは基本的に、ページ内にあるときの最後の要素の値です。ページ内でこれらのエントリを操作するときの条件が必要です
  18. したがって、各エントリにブール値があります。交差しています
  19. これが true の場合、カスタム フックのパラメータを変更します。これにより、API が再度呼び出され、レンダリングも再度実行されます
  20. 最後に、コールバックで渡した要素を観察する必要があるため、要素がある場合はそれを観察するだけです。

コード

カスタムフック.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;

ログイン後にコピー

constants.js

export const API_URL = "https://api.javascripttutorial.net/v1/quotes/"
ログイン後にコピー

以上が簡単なステップで無限スクロールをマスターするの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:dev.to
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート