ホームページ > 記事 > ウェブフロントエンド > React で無限スクロール コンポーネントを構築する
アプリケーションやウェブページ、特にソーシャルメディアではスクロールするだけで済む無限スクロールが見られます。何も考えずにスクロールするのは良くありませんが、独自の無限スクロールを構築するのは素晴らしいことです。開発者として、Web サーフィン中に目にするコンポーネントを再作成してみる必要があります。一部のコンポーネントを実装する際には、より多くのことを学び、既成概念にとらわれずに考えることが求められる場合があります。
また、アプリケーションに無限スクロールを実装したい場合は、ガイドに従って独自のスクロールを作成できます。独自のコードを追加して、スクロールの動作を改善できます。
この記事では、無限スクロール コンポーネントを最初から構築します。以下のトピックについて説明します:
さて、始めましょう。
CRA を使用して基本的な React アプリケーションを作成します。次のコマンドを実行することでこれを行うことができます:
npx create-react-app infinite-scroll
Vite または NextJS を使用したい場合は、それも可能です。マイナーな変更を除けば、その他の点は変わりません。
注: このコマンドを実行するには、NodeJS が事前にインストールされている必要があります。 また、CRA から不要な定型コードの一部を削除します。
API からデータを取得するには、依存関係が 1 つ必要になります。 React を設定したら、次のコマンドで Axios をインストールできます:
npm install axios
これで、コンポーネントを作成する準備が整いました。
Tmdb API から人気のある映画データを取得するコンポーネントを構築します。 API キーは Web サイトから無料で取得できます。まずデータを取得する場所を構築してから、無限スクロール機能を追加しましょう。
アプリ コンポーネントのコードは次のとおりです:
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;
データを取得し、それを小道具として MovieCard コンポーネントに渡しているコードをほぼ理解できます。
各映画の情報を表示するための MovieCard.js コンポーネントを作成します。
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> ); };
アプリケーションの CSS は次のとおりです:
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; }
さて、まず無限スクロールをどのように構築するかを理解しましょう。このために、スクロール バーの位置を見ていきます。スクロール バーの位置がページの終わりのすぐ上にある場合、読み込み状態を true に設定します。
ページの状態を 1 増やす別の useEffect を用意します。ページ番号が更新されると、そのページを依存関係として持つ最初の useEffect がトリガーされます。これにより、 fetchMovie() 関数が呼び出され、データが取得されます。
まず、スクロール バーの位置が変更されたことを知るために listen さえ追加します。
window.addEventListener("scroll", handleScroll);
スクロールが発生すると、スクロール バーの現在の位置が Web ページの下部 (つまり、垂直方向のスクロール可能な領域の合計) のすぐ上にあるかどうかを確認します。 「はい」の場合、読み込み状態を true に変更します。
const handleScroll = () => { if (document.body.scrollHeight - 300 < window.scrollY + window.innerHeight) { setLoading(true); } };
読み込み状態の変更に成功したら、ページ番号をインクリメントする useEffect を実装できます。これにより、ムービー データの取得が可能になります。
useEffect(() => { if (loading == true) { setPage((prevPage) => prevPage + 1); } }, [loading]); // other useEffect that we already implemented useEffect(() => { fetchMovie(); }, [page]);
スクロール中に handleScroll を複数回トリガーできるため、不要な関数の呼び出しが複数回発生します。関数にデバウンスを追加して、関数を呼び出すまでに時間がかかるようにすることができます。
// 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));
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;
これは、アプリケーションの動作を示す GIF です。
React で無限スクロール コンポーネントを構築することは、非常に価値のある経験となる可能性があります。スクロールの仕組みについての理解が深まるだけでなく、状態管理、イベント リスナー、デバウンスなどの最適化テクニックについても学習できます。このガイドに従うことで、必要に応じてカスタマイズおよび改善できる基本的な無限スクロールのセットアップが完了しました。
映画データ、ブログ投稿、その他のコンテンツを表示する場合、このコンポーネントは強力な基盤として機能します。重要なのは、ユーザーがスクロールするときにデータがいつどのようにフェッチされるかを慎重に管理することで、スムーズなユーザー エクスペリエンスを確保することであることに注意してください。コーディングを楽しんでください!
以上がReact で無限スクロール コンポーネントを構築するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。