[React] react-paginate를 이용한 페이지네이션 구현하기

changheeee·2023년 12월 5일
0

전시,공연 정보를 제공하는 리액트 프로젝트에서 공연,전시의 데이터의 양이 많아 한 페이지에 모든 정보를 나열하다보니 사용자 경험이 저하된다는 생각이 들었습니다. 이를 해결하기 위해 페이지네이션을 도입하여 사용자에게 전시공연 정보를 정해진 개수만큼 보여지도록 했습니다.


react-paginate 설치

npm install react-paginate

커스텀 페이지네이션 컴포넌트 생성

설치가 완료되었다면, 이제 'CurrentExhibitions' 컴포넌트에 페이지네이션 기능을 추가해보겠습니다. 먼저, react-paginate를 컴포넌트에서 사용할 수 있도록 import 합니다. 그리고 'Pagination' 컴포넌트를 생성하여 react-paginate를 사용하도록 합니다.

// Pagination.js
import React from "react";
import ReactPaginate from "react-paginate";
import { FiChevronLeft, FiChevronRight } from "react-icons/fi";

const Pagination = ({ pageCount, onPageChange, currentPage }) => {
  return (
    <ReactPaginate
      previousLabel={<FiChevronLeft />}
      nextLabel={<FiChevronRight />}
      pageCount={pageCount}
      onPageChange={onPageChange}
      containerClassName={"pagination"}
      pageLinkClassName={"pagination__link"}
      activeLinkClassName={"pagination__link__active"}
    />
  );
};

export default Pagination;

또한, 페이지네이션 컴포넌트의 스타일을 정의하기 위해 CSS를 작성합니다.

.pagination {
  margin-top: 2rem;
  width: 100%;
  display: flex;
  justify-content: center;
  gap: 1rem;

  > * {
    cursor: pointer;
  }
}

.pagination__link {
  transition: all 0.25s;
  padding: 0.2rem 0.6rem;
  border-radius: 0.3rem;
}

.pagination__link__active {
  background-color: #bbb;
  color: #fefefe;
}

react-paginate 적용

설치가 완료되었다면, 이제 공연,전시 목록을 보여주는 컴포넌트에 페이지네이션 기능을 추가해보겠습니다.

먼저, 앞서 만든 Pagenation컴포넌트를 사용할 수 있도록 import 합니다.

import Pagination from "../atoms/Pagination";

그리고 컴포넌트의 return 부분에서 페이지네이션 컴포넌트를 렌더링하도록 합니다.

// 생략...

return (
  <>
    {/* 생략... */}

    {/* 페이지네이션 */}
      {pageCount > 0 && (
        <Pagination
          pageCount={Math.max(1, pageCount - 1)}
          onPageChange={handlePageChange}
          currentPage={currentPage}
        />
      )}
  </>
);

추가적인 작업

1. 페이지 이동 시 스크롤 조정

페이지네이션을 구현하고 보니 페이지를 넘겨도 화면이 클릭한 위치에 있어 사용자 경험을 저하한다는 생각이 들었습니다.

사용자가 페이지를 이동할 때마다 스크롤이 맨 위로 이동하게 되면, 사용자는 새로운 페이지의 내용을 처음부터 볼 수있을 것입니다. 이를 위해 'handlePageChange' 함수 내부에 window.scrollTo() 함수를 사용하여 스크롤 위치를 새로운 페이지의 첫부분이 보이도록 조정하였습니다.

const handlePageChange = ({ selected }) => {
  setCurrentPage(selected);
  window.scrollTo(0, 320); // 페이지 변경 시 스크롤을 맨 위로 이동
};

2. 카테고리 필터링 및 정렬

기존에는 데이터를 한번에 처리해서 개별 카테고리 탭을 눌러도 전체에 대한 페이지네이션이 남아있는 문제가 있었습니다. 이를 해결하기 위해 각 카테고리 탭에 따라 보여지는 데이터를 필터링하고 정렬하였습니다. 선택된 카테고리에 따라 필터링된 데이터를 'setFilteredData'를 통해 업데이트하였고, 이에 따라 페이지네이션의 전체 페이지 수도 변경되게 하였습니다.

useEffect(() => {
  // 카테고리 변경 시 필터링된 데이터 업데이트
  const filtered = data
    .filter(
      (item) =>
        (selectedCategory === "전체" || item.category === selectedCategory) &&
        formatDate(item.start) <= new Date() &&
        formatDate(item.end) >= new Date()
    )
    .sort((a, b) =>
      sortType === "bookmarked"
        ? b.bookmarked - a.bookmarked
        : new Date(b.start) - new Date(a.start)
    );

  setFilteredData(filtered);
  setCurrentPage(0); // 페이지를 처음으로 초기화
}, [data, selectedCategory, sortType]);

완성

[react-paginate 공식문서]
https://www.npmjs.com/package/react-paginate

[깃허브]
https://github.com/changheeee/BEG

0개의 댓글