이전에 mui 라이브러리를 사용해서 페이지네이션을 구현했었다.
mui 라이브러리를 사용한 페이지네이션 구현
💬 아무래도 페이지네이션 하나만을 위해 CSS 라이브러리를 설치해 사용하는 것은 사용에 비해 무거울 수 있다는 생각이 들어 tailwind로 다시 만들어보기로 했다.
interface Props {
pageCount: number
currentPage: number
onPageChange: (e: React.ChangeEvent<unknown>, value: number) => void
}
const Pagination = ({ pageCount, currentPage, onPageChange }: Props) => {
페이지네이션을 하기 위해 필요한 pageCount(전체 페이지 수), currentPage(현재 페이지), onPageChange(페이지 이동 함수) 값을 받아온다.
if (pageCount === 0) return
페이지 수가 0일 경우 페이지네이션이 보이는 것은 이상하니 아무것도 return 하지 않도록 하여 컴포넌트가 출력되지 않도록 한다.
페이지네이션은 아래의 이미지와 같이 맨앞 버튼, 맨뒤 버튼, 이전 버튼, 다음 버튼, 페이지 버튼으로 구성하기로 한다.
또한 5페이지 이상일 경우 그 이후 페이지가 ...으로 생략되도록 한다.
한번에 보일 수 있는 최대 페이지 수는 5로 설정한다.
const MAX_VISIBLE_PAGES = 5
1) 시작 페이지
const startPage = Math.max(1, currentPage - Math.floor(MAX_VISIBLE_PAGES / 2))
const endPage = Math.min(pageCount, startPage + MAX_VISIBLE_PAGES - 1)
const pages = Array.from(
{ length: endPage - startPage + 1 },
(_, index) => startPage + index,
)
// 1보다 시작 페이지가 크면 ...를 출력
{startPage > 1 && (
<li className="px-4 py-2 rounded cursor-not-allowed">...</li>
)}
{pages.map((page) => (
<li
key={page}
className={`${
currentPage === page
? " text-black bg-main-lime"
: " text-[#777777] hover:bg-gray-200"
} cursor-pointer px-3 py-1 rounded `}
onClick={(e) => onPageChange(e, page)}
>
{page}
</li>
))}
// 끝 페이지보다 총 페이지 수가 크면 ... 출력
{endPage < pageCount && (
<li className="px-4 py-2 rounded cursor-not-allowed">...</li>
)}