React infinite scroll

2022. 11. 30. 23:36React

반응형

react-infinite-scroll-component 라이브러리를 이용하여서 페이징 처리에 대해 알아보도록 하자.

 

프로젝트 설정 및 라이브러리 설치

Tailwind 프로젝트 설정

사이트: https://tailwindcss.com/docs/guides/create-react-app

 

Install Tailwind CSS with Create React App - Tailwind CSS

Setting up Tailwind CSS in a Create React App project.

tailwindcss.com

 

react-infinite-scroll-component 설치

사이트: https://www.npmjs.com/package/react-infinite-scroll-component

 

react-infinite-scroll-component

An Infinite Scroll component in react.. Latest version: 6.1.0, last published: 2 years ago. Start using react-infinite-scroll-component in your project by running `npm i react-infinite-scroll-component`. There are 342 other projects in the npm registry usi

www.npmjs.com

 

tailwind-scrollbar-hide 설치

사이트: https://www.npmjs.com/package/tailwind-scrollbar-hide

 

tailwind-scrollbar-hide

tailwindcss plugin for hide scrollbar. Latest version: 1.1.7, last published: a year ago. Start using tailwind-scrollbar-hide in your project by running `npm i tailwind-scrollbar-hide`. There are 32 other projects in the npm registry using tailwind-scrollb

www.npmjs.com

 

The movie database API 인증키 발급

사이트: https://www.themoviedb.org

 

The Movie Database (TMDB)

Welcome. Millions of movies, TV shows and people to discover. Explore now.

www.themoviedb.org

 

App.js

import React, { useState, useEffect } from "react";
import InfiniteScroll from "react-infinite-scroll-component";

// API Key
const key = "APIKey";

export default function App() {
  const [movies, setMvoies] = useState([]);

  const [hasMore, sethasMore] = useState(true);

  const [page, setpage] = useState(2);

  useEffect(() => {
    const initMovies = async () => {
      const response = await fetch(
        `https://api.themoviedb.org/3/movie/popular?api_key=${key}&language=en-US&page=1`
      );
      const data = await response.json();
      setMvoies(data.results);
    };

    initMovies();
  }, []);

  // fetch movies
  const fetchMovies = async () => {
    const response = await fetch(
      `https://api.themoviedb.org/3/movie/popular?api_key=${key}&language=en-US&page=${page}`
    );
    const data = await response.json();

    return data.results;
  };

  // fetch data
  const fetchData = async () => {
    const userMovies = await fetchMovies();
    console.log(userMovies);

    setMvoies([...movies, ...userMovies]);
    if (userMovies.length === 0 || userMovies.length < 20) {
      sethasMore(false);
    }

    setpage(page + 1);
  };

  return (
    <div id="scrollableDiv" className="h-[800px] overflow-y-auto scrollbar-hide">
      <InfiniteScroll
        dataLength={movies.length}                            // ① 반복되는 컴포넌트의 개수
        next={fetchData}                                      // ② 스크롤이 화면 맨 아리에 닿았을때 호출 되는 함수
        hasMore={hasMore}                                     // ③ 추가 데이터가 있는지 여부
        loader={<h4>Loading...</h4>}
        scrollableTarget="scrollableDiv"
        endMessage={
          <p style={{ textAlign: "center" }}>
            <b>Yay! You have seen it all</b>
          </p>
        }
      >
        <div className="w-full p-6">
          {movies.map((item, id) => (
            <div
              key={id}
              className="w-[190px] sm:w-[230px] md:w-[270px] lg:w-[310px] inline-block cursor-pointer relative p-2"
            >
              <img
                className="w-full h-auto block"
                src={`https://image.tmdb.org/t/p/w500/${item?.backdrop_path}`}
                alt={item?.title}
              />
              <div className="absolute top-0 left-0 w-full h-full hover:bg-black/80 opacity-0 hover:opacity-100 text-white">
                <p className="whitespace-normal text-xs md:text-sm font-bold flex justify-center items-center h-full text-center">
                  {item?.title}
                </p>
              </div>
            </div>
          ))}
        </div>
      </InfiniteScroll>
    </div>
  );
}

사용 방법은https://www.npmjs.com/package/react-infinite-scroll-component 사이트를 참고 하면 됩니다. 

소스에서 가장 중요한 부분에 대해서 설명 하겠습니다.

① dataLength 속성은 반복되는 컴포넌의 개수 입니다. The movie database API 에서 인기 있는 영화 
    목록을 조회하는데 페이지당 20개의 데이터를 받기 때문에 dataLength 속성은 movies.length 로 
    지정 합니다.

② next 속성은 스크롤이 화면 맨아래 닿았을때 호출이 되는 함수인데 모니터의 해상도가 높은 경우 
    20개의 이미지를 불러와도 화면에 꽉차지 않기때문에 스크롤이 안되는 현상이 발생 하였습니다.
   이를 해결하기 위해 InfiniteScroll 컴포넌트를 감싸는 div 태그에 id=”scrollableDiv” 를 지정 하고 

   infiniteScroll의 scrollableTarget 속성에 scrollableDiv 지정 합니다.

   그리고 scollbar를 숨기기 위해서 scrollbar-hide 속성을 사용하여서 scrollbar 숨김처리를 해줍니다.

③ hasMore 속성은 데이터가 더 있는 경우 스크롤을 계속 해주고 그렇지 않으면 endMessage 속성
    에 정의된 메세지를 출력하고 끝납니다.
    hasMore 처리로직은 페이지당 20개의 데이터를 불러오게 되는데 마지막에는 0이거나 20개이하
    이기 때문에 불러온 데이터의 length 로 판단 합니다.

 

데모 화면

 

소스다운로드

https://github.com/roopy1210/react-infinite-scroll

 

GitHub - roopy1210/react-infinite-scroll

Contribute to roopy1210/react-infinite-scroll development by creating an account on GitHub.

github.com

 

반응형

'React' 카테고리의 다른 글

윈도우 React https 적용하기  (0) 2023.05.16