React에서 페이지네이션 구현하기

realzu·2022년 8월 18일
0

React에서 페이지네이션을 만드는 방법을 알아보겠다! 페이징은 리스트가 있는 모든 곳에서 사용해야 하기 때문에 Pagination이라는 컴포넌트를 따로 만들 것이다. 타입스크립트를 함께 사용했으니 타입은 추가로 확인하면 된다.

📍 사용할 값

앞으로 사용할 변수들을 소개하겠다!

curPage : 현재 페이지 번호
totalPage : 전체 페이지 수
totalCount : 전체 데이터 수
size : 페이지 당 게시물 수
pageCount : 화면에 나타날 페이지 갯수

📍 컴포넌트 props

페이징을 쓸 여러 파일에서는 페이지네이션을 불러올 때 각각 사용할 값들을 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 는 직접 지정하면 되는 값.
totalCounttotalPage는 데이터 수에 따라 바뀔 것이다.

🔹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 }

📍 JSX 처리

🔹 '<' 와 '>'의 양쪽 값 계산

양쪽의 버튼을 누를 때마다 페이지 그룹이 이동해야 한다. 따라서 각각 onClick 을 통해 pageGroup을 바꾼다. 또한 더 이상 값이 없을 때에는 disable 속성을 주었다.

return (
  <Nav>
    <SideBtn onClick={()=>setPageGroup(pageGroup-1)} disabled={firstNum === 1}>&lt;</SideBtn>
    {pagination()}
    <SideBtn onClick={()=>{setPageGroup(pageGroup+1)}} disabled={lastNum === totalPage}>&gt;</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

profile
부딪히지 않으면 아무 일도 일어나지 않는다 👊

1개의 댓글

comment-user-thumbnail
2023년 7월 15일

잘보고 갑니다!!

답글 달기