Pagination component 사용 시 아래와 같이 사용한다
const [currentPage, setCurrentPage] = useState(1);
const [lastPage, setLastPage] = useState(0); // api 통신 후 값을 업데이트 해줌
const onChangePage = (newPage: number) => {
setCurrentPage(newPage)
}
...
return (
...
<Pagination currentPage={currentPage} lastPage={lastPage} onPageChange={onChangePage} />
...
)
Pagination component에서는 currentPage, lastPage, 페이지를 업데이트할 수 있는 함수를 전달받는다
currentPage와 lastPage가 업데이트될 때마다 화면에 보여줄 페이지 리스트를 계산해 줬다 👍
page가 1페이지인 경우 더 앞으로 갈 수 없도록 앞으로 가기 버튼을 disabled 시켰고
마지막 페이지인 경우에도 뒤로 갈 수 없도록 뒤로 가기 버튼을 disabled 처리했다
import React, { useEffect, useState } from 'react'
import ArrowLeftIcon from 'src/assets/icon/common/ico_arrow_left.svg'
import ArrowRightIcon from 'src/assets/icon/common/ico_arrow_right.svg'
import { Spartan } from 'src/styles/mixin/mixin'
import styled from 'styled-components'
interface PaginationProps {
currentPage: number // 현재 페이지
lastPage: number // 마지막 페이지
onPageChange: (page: number) => void // 현재 페이지 값을 업데이트하는 함수
}
const Pagination = ({ currentPage, lastPage, onPageChange }: PaginationProps) => {
const DISPLAYRANGE = 5 // 화면에 보여줄 페이지의 개수
const [pageList, setPageList] = useState<number[]>([]) // 화면에 보여줄 페이지 list
useEffect(() => {
setPageList([])
const pageGroupNum = Math.ceil(currentPage / DISPLAYRANGE) // 페이지 그룹 번호
for (
let i = (pageGroupNum - 1) * DISPLAYRANGE + 1;
i <= pageGroupNum * DISPLAYRANGE && i <= lastPage;
i++
) {
setPageList((prev) => [...prev, i])
}
}, [currentPage, lastPage]) // currentPage, lastPage가 변경될 때마다 다시 실행
return (
<PaginationWrapper>
<ArrowBtn
onClick={() => onPageChange(currentPage > 1 ? currentPage - 1 : 1)}
disabled={currentPage === 1}
>
<ArrowLeftIcon fill={currentPage === 1 ? '#eee' : '#999'} width={24} height={24} />
</ArrowBtn>
{pageList.map((page) => (
<PaginationBtn
key={page}
isActive={currentPage === page}
onClick={() => onPageChange(page)}
>
<span>{page}</span>
</PaginationBtn>
))}
<ArrowBtn
onClick={() => onPageChange(currentPage < lastPage ? currentPage + 1 : 1)}
disabled={currentPage === lastPage}
>
<ArrowRightIcon fill={currentPage === lastPage ? '#eee' : '#999'} width={24} height={24} />
</ArrowBtn>
</PaginationWrapper>
)
}
const PaginationWrapper = styled.div`
display: flex;
justify-content: center;
gap: 32px;
margin: 48px 0px;
`
const ArrowBtn = styled.button`
display: flex;
justify-content: center;
align-items: center;
width: 30px;
height: 30px;
padding: 0px;
`
const PaginationBtn = styled.button<{ isActive: boolean }>`
display: flex;
justify-content: center;
align-items: center;
width: 30px;
height: 30px;
padding: 4px;
font-size: 16px;
color: ${(props) =>
props.isActive ? props.theme.colors.primaryWhite : props.theme.colors.secondaryGray2};
background-color: ${(props) => (props.isActive ? props.theme.colors.primaryBlue : 'transparent')};
border-radius: 100%;
> span {
${[Spartan]}
}
`
export default Pagination
이렇게 해서 만들면 잘 작동한다!
나의 경우 거의 모든 페이지에서 페이지네이션이 필요했다
Pagination component에 값을 전달해 주고 페이지 관련 내용을 상태관리 하기 위해서 (currentPage, perPage...)
많은 보일러플레이트가 만들어지고 있었다...!
다음 포스팅에서는 이를 한 번에 관리하기 위한 Pagination 관련 custom hook에 대해서 써보겠다~!
'IT > React' 카테고리의 다른 글
Pagination custom hook (0) | 2023.11.06 |
---|---|
[React] Button Component 잘 만드는 방법! (0) | 2023.11.05 |
React cdn 방식으로 시작하기 (php파일에서 리액트 사용하기) (0) | 2022.06.02 |
듀얼 셀럭터 (0) | 2022.04.15 |
댓글 대댓글 추가하기 (0) | 2022.04.12 |