Programming/Client

[React] 프론트단에서 페이지네이션 구현하기

Jiwoo 2023. 2. 15. 21:50

들어가기 전에...

유저가 많고 데이터가 방대한 서비스라면 백단에서 페이지에 따라

데이터를 나눠서 넘겨줘야 하고, 그것이 이상적인 구조이다.

하지만 내가 진행하는 프로젝트는 작은 서비스이고

백의 인력이 너무나 부족해서 페이지네이션 API를 구현할 여력이 없었다.

그래서 프론트단에서 데이터 전체를 받아와서

직접 나누어 출력하는 페이지네이션 컴포넌트를 구현했다.


📌 컴포넌트 구현

import { useState } from "react";
import { PageWrapper, PageBtn } from "../styles/Styled";

// total(데이터 총 갯수), limit(한 페이지에 보여줄 갯수)
const Pagination = ({ total, limit, page, setPage }) => {
  const [btnActive, setBtnActive] = useState(""); // 현재 페이지 활성화 여부
  const numPages = Math.ceil(total / limit); // 총 페이지 수는 올림해야 함

  const hadlePageBtn = (e, i) => {
    setPage(i + 1);
    setBtnActive(e.target.value);
  };

  return (
    <>
      <PageWrap>
        <PageBtn onClick={() => setPage(page - 1)} disabled={page === 1}>
          &lt;
        </PageBtn>
        {Array(numPages)
          .fill()
          .map((_, i) => (
            <PageBtn
              value={i}
              key={i + 1}
              {/*현재 페이지 비활성화하기 위해 클래스명 지정*/}
              className={i === btnActive ? "active" : ""} 
              onClick={(e) => hadlePageBtn(e, i)}
              aria-current={page === i + 1 ? "page" : null}
            >
              {i + 1}
            </PageBtn>
          ))}
        <PageBtn onClick={() => setPage(page + 1)} disabled={page === numPages}>
          &gt;
        </PageBtn>
      </PageWrap>
    </>
  );
};

export default Pagination;

현재 클릭된 페이지와 클릭되지 않은 페이지를 구별하기 위해

btnActive라는 상태값을 추가해서 클래스명을 다르게 표시했다.

이렇게 하면 페이지가 클릭되면 이에 맞춰 다른 데이터가 출력된다.


📌 컴포넌트 적용하기

  1. import 하기
    import Pagination from './Pagination';
  2. 페이지 상태값 만들기
    const [page, setPage] = useState(1);
  3. offset (데이터 시작 위치) 설정하기
    const offset = (page - 1) * 한 페이지에 들어갈 갯수;
  4. 받아오는 데이터 가공하기
    let 뿌리는데이터 = 원본데이터.slice(offset, offset + 10);
  5. props 넣어 페이지네이션 넣기
    <Pagination total={데이터 갯수} limit={한 화면에 보여줄 개수} page={page} setPage={setPage}/>

예시

import Pagination from "./Pagination";

function Component() {
  const [datas, setDatas] = useState([]);
  const [limit, setLimit] = useState(10);
  const [page, setPage] = useState(1);
  const offset = (page - 1) * limit; // 데이터 시작 번호

  // 데이터 받아와서  setDatas(받은 데이터) 저장

  return (
    <div>
        <main>
        {datas.slice(offset, offset + limit).map((data}) => (데이터 출력되는 형태))}
        </main>
        <Pagination
        total={datas.length}
        limit={10}
        page={page}
        setPage={setPage}
        />
    </div>
  );
}


참고

React로 페이지네이션 UI 구현하기