우리는 애플리케이션과 웹 페이지, 특히 스크롤하기만 원하는 소셜 미디어에서 무한 스크롤을 봅니다. 아무 생각 없이 스크롤하는 것은 좋지 않지만, 자신만의 무한 스크롤을 만드는 것은 멋진 일입니다. 개발자로서 우리는 웹서핑을 하면서 보는 컴포넌트를 재현하려고 노력해야 합니다. 일부 구성 요소를 구현할 때 더 많은 것을 배우고 고정관념에서 벗어나 생각해야 할 수도 있습니다.
또한 애플리케이션에 무한 스크롤을 구현하려는 경우 가이드에 따라 직접 만들 수 있습니다. 스크롤 동작을 개선하기 위해 자신만의 코드를 추가할 수 있습니다.
이 문서에서는 처음부터 무한 스크롤 구성 요소를 구축해 보겠습니다. 다음 주제를 다룹니다:
자, 시작해 보겠습니다.
CRA를 사용하여 기본 React 애플리케이션을 만들 예정입니다. 다음 명령을 실행하면 됩니다:
npx create-react-app infinite-scroll
Vite나 NextJS를 원하시면 그렇게 하셔도 됩니다. 사소한 변경 사항을 제외하고 다른 사항은 동일하게 유지됩니다.
참고: 이 명령을 실행하려면 NodeJS가 사전 설치되어 있어야 합니다. 또한 CRA에서 불필요한 상용구 코드 중 일부를 제거합니다.
API에서 데이터를 가져오려면 하나의 종속성이 필요합니다. React를 설정한 후 다음 명령을 사용하여 Axios를 설치할 수 있습니다:
npm install axios
이제 컴포넌트를 생성할 준비가 되었습니다.
Tmdb API에서 인기 영화 데이터를 가져오는 구성 요소를 구축할 예정입니다. 무료로 해당 웹사이트에서 API 키를 얻을 수 있습니다. 먼저 데이터를 가져오는 위치를 구축한 다음 무한 스크롤 기능을 추가해 보겠습니다.
앱 구성요소의 코드는 다음과 같습니다.
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 (); } export default App;Popular movies according to Tmdb {data.length > 1 && data.map((item) => { return (); })} {loading && Loading....
}
데이터를 가져와 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 (); };{title}
{description}
{rating.toFixed(1)}⭐
다음은 애플리케이션의 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() 함수가 호출되어 데이터를 가져옵니다.
먼저 스크롤바 위치가 변경될 때 알림을 받는 기능을 추가하겠습니다.
window.addEventListener("scroll", handleScroll);
스크롤이 발생하면 스크롤바의 현재 위치가 웹페이지 하단 바로 위에 있는지(예: 전체 수직 스크롤 가능 영역) 확인하겠습니다. 그렇다면 로딩 상태를 true로 변경합니다.
const handleScroll = () => { if (document.body.scrollHeight - 300
로드 상태를 성공적으로 변경한 후 페이지 번호를 증가시키는 useEffect를 구현할 수 있습니다. 그러면 영화 데이터를 가져오는 일이 발생할 수 있습니다.
useEffect(() => { if (loading == true) { setPage((prevPage) => prevPage 1); } }, [loading]); // other useEffect that we already implemented useEffect(() => { fetchMovie(); }, [page]);
스크롤은 스크롤하는 동안 handlerScroll을 여러 번 실행할 수 있으므로 불필요한 함수 호출이 여러 번 발생합니다. 함수를 호출하기 전에 시간이 좀 걸릴 수 있도록 함수에 디바운스를 추가할 수 있습니다.
// 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 { func(...args); }, delay); }; } window.addEventListener("scroll", debounce(handleScroll, 500)); useEffect(() => { if (loading == true) { setPage((prevPage) => prevPage 1); } }, [loading]); return (); } export default App;Popular movies according to Tmdb {data.length > 1 && data.map((item) => { return (); })} {loading && Loading....
}
다음은 애플리케이션의 작동을 보여주는 GIF입니다.
React에서 무한 스크롤 구성 요소를 구축하는 것은 매우 보람 있는 경험이 될 수 있습니다. 스크롤 작동 방식에 대한 이해를 높일 뿐만 아니라 상태 관리, 이벤트 리스너 및 디바운싱과 같은 최적화 기술에 대해서도 알려줍니다. 이 가이드를 따르면 이제 필요에 따라 사용자 정의하고 개선할 수 있는 기본 무한 스크롤 설정이 완료되었습니다.
영화 데이터, 블로그 게시물 또는 기타 콘텐츠를 표시하는 경우 이 구성 요소는 강력한 기반 역할을 합니다. 핵심은 사용자가 스크롤할 때 데이터를 가져오는 시기와 방법을 신중하게 관리하여 원활한 사용자 환경을 보장하는 것입니다. 즐거운 코딩하세요!
부인 성명: 제공된 모든 리소스는 부분적으로 인터넷에서 가져온 것입니다. 귀하의 저작권이나 기타 권리 및 이익이 침해된 경우 자세한 이유를 설명하고 저작권 또는 권리 및 이익에 대한 증거를 제공한 후 이메일([email protected])로 보내주십시오. 최대한 빨리 처리해 드리겠습니다.
Copyright© 2022 湘ICP备2022001581号-3