React에서 페이지네이션을 만드는 방법을 알아보겠다! 페이징은 리스트가 있는 모든 곳에서 사용해야 하기 때문에 Pagination
이라는 컴포넌트를 따로 만들 것이다. 타입스크립트를 함께 사용했으니 타입은 추가로 확인하면 된다.
앞으로 사용할 변수들을 소개하겠다!
curPage : 현재 페이지 번호
totalPage : 전체 페이지 수
totalCount : 전체 데이터 수
size : 페이지 당 게시물 수
pageCount : 화면에 나타날 페이지 갯수
페이징을 쓸 여러 파일에서는 페이지네이션을 불러올 때 각각 사용할 값들을 props로 전달하게 한다. 'DailyLook'이라는 파일을 예시로 가져왔다.
//DailyLook.tsx
const DailyLook = () => {
const [curPage, setCurPage] = useState(1);
//생략
return (
//생략
<Pagination curPage={curPage} setCurPage={setCurPage} totalPage={page.totalPages}
totalCount={page.totalElements} size={page.size} pageCount={5}/>
)
}
🔹curPage
, setCurPage
: useState를 통해 기본값 1로 설정하며, 페이지를 클릭할 때마다 바뀌게 할 것이다.
🔹totalPage
, totalCount
, size
: 우리는 백엔드에서 해당 페이징 값을 미리 넘겨주기 때문에 axios로 받은 값을 표기했다. 하지만 그렇지 않다면 아래의 계산식을 참고하자.
totalPage = Math.ceil(totalCount / size)
size
는 직접 지정하면 되는 값.
totalCount
와 totalPage
는 데이터 수에 따라 바뀔 것이다.
🔹pageCount
: 각 페이지마다 보여줄 값을 세팅해서 넘겨주면 된다.
이제 다시 Pagination 컴포넌트로 돌아오자! 위에서 넘겨준 값을 받아서 본격적으로 페이징 처리를 해야 한다.
🔹 현재 페이지의 그룹
지금 누르고 있는 페이지가 몇번째 페이지 그룹에 속해있는지 계산한다.
const [pageGroup,setPageGroup] = useState((Math.ceil((curPage) / pageCount)))
🔹 그룹 내 첫/마지막 번호
그룹 안에서 보여질 첫번째와 마지막 숫자를 계산한다. 페이징 계산의 논리 식이다. 또한 모두 if문으로 예외 사항을 처리하였다.
let lastNum = pageGroup * pageCount
if (lastNum > totalPage) { lastNum = totalPage }
let firstNum = lastNum - (pageCount - 1)
if (pageCount > lastNum) { firstNum = 1 }
🔹 '<' 와 '>'의 양쪽 값 계산
양쪽의 버튼을 누를 때마다 페이지 그룹이 이동해야 한다. 따라서 각각 onClick
을 통해 pageGroup
을 바꾼다. 또한 더 이상 값이 없을 때에는 disable 속성을 주었다.
return (
<Nav>
<SideBtn onClick={()=>setPageGroup(pageGroup-1)} disabled={firstNum === 1}><</SideBtn>
{pagination()}
<SideBtn onClick={()=>{setPageGroup(pageGroup+1)}} disabled={lastNum === totalPage}>></SideBtn>
</Nav>
);
🔹 페이지 버튼 반복
JSX에서 반복문을 넣으려면 따로 함수를 만들어야 한다. 따라서 pagination
이라는 함수를 만들었다. 버튼을 클릭할 때 마다 onClick
에 의해 현재 페이지 번호의 값도 바뀌게 된다. i라는 속성을 넣은 이유는 style에 props를 넘겨주기 위해 추가하였다.
const pagination = () => {
let arr = []
for (let i = firstNum; i <= lastNum; i++) {
arr.push(
<PgBtn key={i} onClick={()=>setCurPage(i)} i={i} curPage={curPage}>{i}</PgBtn>
)
}
return arr;
}
Styled-Component를 사용하여 버튼 스타일을 만들었다. 위에서 넘긴 i를 받아서 i가 현재 페이지일 때 파란색으로 변하게 했다.
const PgBtn = styled(Btn)<activeT>`
${
props => props.i === (props.curPage) &&
css`
background-color: skyblue;
font-weight: bold;
cursor: revert;
transform: revert;
`
}
`;
위에서 사용한 타입이다. 타입스크립트를 사용한다면 추가해야 한다!
interface PropsT {
setCurPage :React.Dispatch<React.SetStateAction<number>>,
curPage :number,
totalPage :number,
totalCount :number,
size :number,
pageCount :number,
}
interface activeT {
i :number,
curPage :number
}
이렇게 해서 페이지네이션의 알고리즘과 코드를 알아보았다!! 클릭할 때마다 값들이 바뀌어야 하기 때문에, 조금 복잡하기도 하지만 나름 간결(?)하게 설명하려고 노력했다😄 페이징 처리하다가 다른 값이 바뀐다던지 애를 먹어서 중간중간 포기하려다가,, 마음을 다잡고 이렇게 완성했다💞
아래의 링크로 들어가면 전체 코드를 볼 수 있으니 참고 바랍니다!
궁금한 사항이 있다면 댓글로 편하게 남겨주세요
https://github.com/look-outside/front-end/blob/main/src/components/Pagination.tsx
cf)
https://min-kyung.tistory.com/30
https://ts2ree.tistory.com/150?category=518808
https://www.daleseo.com/react-pagination/
https://seoyun-is-connecting-the-dots.tistory.com/322
잘보고 갑니다!!