Pagination

이태곤·2024년 2월 21일
0

CS

목록 보기
21/23

1. Pagination Component 구성

import classNames from "classnames";
import { Link } from "react-router-dom";
import { useLocation } from "react-router-dom";

export default function Pagination({
  page, // 현재 페이지 번호
  totalPages, // 전체 페이지 수
  paginationSize, // 페이지네이션에서 한 번에 보여줄 페이지의 수
  onChange, // 페이지 변경 시 호출할 함수
}) {
  let pageNumber = page; // 현재 페이지 번호를 로컬 변수에 할당
  let startPage =
    Math.floor((pageNumber - 1) / paginationSize) * paginationSize + 1; // 현재 표시되는 페이지네이션 범위의 시작 페이지 계산
  let endPage = startPage + paginationSize - 1; // 현재 표시되는 페이지네이션 범위의 끝 페이지 계산

  const location = useLocation(); // 현재 위치(브라우저의 URL)를 가져오는 Hook
  const searchParams = new URLSearchParams(location.search); // URL의 쿼리 스트링을 다루기 위한 객체

  return (
    <>
      <div className={classNames("left-arrow")}>
        {startPage > 1 && ( // 시작 페이지가 1보다 큰 경우에만 이전 페이지로 이동할 수 있는 링크 표시
          <Link
            to={`${location.pathname}?${searchParams.toString()}`}
            state={{ page: startPage - 1 }}
          >
            &lt;
          </Link>
        )}
      </div>
      <div className={classNames("page-number")}>
        {Array.from(
          { length: Math.min(totalPages, endPage) - startPage + 1 }, // 시작 페이지부터 끝 페이지까지 또는 전체 페이지 수까지의 범위를 배열로 생성
          (_, index) => startPage + index // 배열을 만들어 각 페이지 번호를 할당
        ).map((pageNumber, index) => {

          return (
            <Link
              to={`?page=${pageNumber}`} // 링크의 대상 URL 설정
              state={{ page: pageNumber }} // 링크 클릭 시 전달할 상태 설정
              className={classNames("page-item")}
              key={index} // React 요소 리스트의 각 항목에 대해 고유한 키 제공
              onClick={() => onChange(pageNumber)} // 페이지 번호 클릭 시 onChange 함수 호출
            >
              {pageNumber}
            </Link>
          );
        })}
      </div>
      <div className={classNames("right-arrow")}>
        {endPage < totalPages && ( // 끝 페이지가 전체 페이지 수보다 작은 경우에만 다음 페이지로 이동할 수 있는 링크 표시
          <Link to={`?page=${endPage + 1}`} state={{ page: endPage + 1 }}>
            &gt;
          </Link>
        )}
      </div>
    </>
  );
}

2. Pagination Component 적용

  1. 페이지네이션을 적용한 컴포넌트에 다음과 같이 import
import Pagination from "../components/Pagination"; //경로에 따라 수정
  1. 페이지네이션 변수를 관리하기 위한 useState 추가
  const [page, setPage] = useState(1); //초기값
  const [totalPages, setTotalPages] = useState(1); //초기값
  1. 페이지네이션 div에 다음과 같은 코드 작성
<div className={classNames("paginate")}>
            <Pagination
              page={page}
              totalPages={totalPages}
              paginationSize={5} //5페이지 단위로 표시 (변경 가능)
              onChange={search}
            />
</div>
  1. 페이지네이션을 적용시킬 함수 선언
 const search = (pageNumber = 1) => {
    getAccountList({
      //필요한 필드 추가
      page: pageNumber - 1, //페이지에 대한 데이터 요청
    }).then((response) => {
      //필요 로직 작성
      setPage(response.data.pageInfo.page + 1); //서버에서 0 기반 페이지 인덱싱을 사용
      setTotalPages(response.data.pageInfo.totalPages);
    });
  };
  1. URL의 location 상태 변경을 감지하여, 페이지 번호를 업데이트
  useEffect(() => {
    if (location.state && location.state.page) {
      setPage(location.state.page);
    }
  }, [location]);
  • 사용자가 페이지 번호를 클릭할 때, 해당 페이지 번호를 location의 state로 설정하고, 컴포넌트가 리렌더링되면서 useEffect 내부의 로직이 실행된다.
<Link
    to={`?page=${pageNumber}`}
    state={{ page: pageNumber }}
    className={classNames("page-item")}
    key={index}
    onClick={() => onChange(pageNumber)}
    >
    {pageNumber}
</Link>

0개의 댓글