[Project] Hobbyt - Pagination 개발하기

Heera1·2023년 4월 6일
0
post-thumbnail

1. 데이터가 들어오고 있는 형식

api 요청은 아래와 같이 보내면 된다.
http://생략/api/members/myPage/products?page=0&size=10

페이지네이션을 클릭 시 클릭한 버튼의 value 값(1을 눌렀음 1을, 2를 눌렀음 2를)을 page=${value} 로 보내는 방법을 사용할 생각이다.


2. matarial-ui pagination 사용하기

페이지네이션을 직접 개발할 수도 있겠지만 라이브러리를 사용해 보기로 했다. bootstrap은 부트캠프 당시 사용해본적이 있지만 mui는 사용해본적이 없어 mui pagination을 선택했다.


2-1. 다운로드

npm install @mui/material @emotion/react @emotion/styled

https://mui.com/material-ui/react-pagination/#main-content
mui 홈페이지에서 원하는 페이지네이션 코드를 긁어온다.



3. 적용하기

페이지네이션이 필요한 파일에 복사한 코드를 붙여넣기 한다.
프로젝트에선 내 정보 페이지의 "판매작품", "구매작품", "판매관리" 페이지에서 필요했기 때문에 각각의 페이지에서 불러와줬다.

import Pagination from "@mui/material/Pagination";
import Stack from "@mui/material/Stack";

export default function ProductstList() {
	const [data, setData] = useState<ProductListType[]>([]);
  	// 페이지네이션
  	const [page, setPage] = useState(0);
  	const [totalPages, setTotalPages] = useState([]);
  
  	const handlePageChange = (e, value) => {
    	setPage(value - 1);
  	};
  
    useEffect(() => {
  	  const getData = async () => {
    	  	const res = await getProductsList(page);
      		setData(res.data);
      		setTotalPages(res.data.pageInfo);
    	};
    	getData();
  	}, [page]);
  
 return (
 	    <div className="flex justify-center mt-20">
          {totalPages && (
            <Stack spacing={2}>
              <Pagination
                count={totalPages.totalPages}
                defaultPage={1}
                shape="rounded"
                size="large"
                onChange={(e, value) => handlePageChange(e, value)}
                defaultValue={1}
                boundaryCount={2}
              />
            </Stack>
          )}
        </div>
 )
  • page의 기본값을 0으로 설정한다.
    기본값을 0으로 지정하는 이유는 응답값 때문이다. 총 데이터가 16개라고 가정했을 때, page=1 라고 요청 보낸다면 1페이지에 10개 데이터가 page=2라고 요청 보냈을 때는 2페이지에 6개의 데이터가 들어올 것이라고 생각하게 된다. 하지만 page=1 라고 요청을 보내면 2페이지의 데이터 6개가 들어오게 된다. 확실하진 않지만 DB에 저장되는 값이 0부터 시작해서 그러는 것 같다. 그렇기 때문에 page의 기본값은 0부터 시작하는 것으로 설정하였다.

  • totalPages에는 서버에서 보내주는 데이터에서 페이지에 대한 정보를 담고 있는 pageInfo를 저장한다.
  • setPage(value - 1) 페이지네이션을 클릭하면 handlePageChange 함수가 실행된다. 이때 value 값은 클릭한 페이지네이션 버튼의 값이다. 즉, 1을 클릭하면 value=1 이고, 3을 클릭했으면 value=3이 된다. 위의page 에서 적었듯이 page는 0부터 시작한다. 페이지네이션 버튼에는 0이 없고, 1부터 시작하기 때문에 원하는 페이지의 제대로된 정보를 불러오기 위해선 value 값에서 1을 빼줘야한다.

페이지네이션에서 사용 가능한 props들은 아래 링크에서 확인할 수 있다.
https://mui.com/material-ui/api/pagination/

사용한 props들만 작성해보자면

  • count : 총 페이지 갯수. useEffect를 통해 데이터를 불러온 뒤totalPages에 저장해두었던 값 중 totalPages를 사용한다.
  • defalutPage : 기본적으로 선택되어 있는 페이지. 1로 설정해두었다.
  • shape : 페이지네이션 버튼의 모양을 어떻게 할 것인지. 'circular'와'rounded' 중 선택 가능하다.
  • size : 페이지네이션 컴포넌트의 크기를 어떻게 할 것인지.
  • onChange : 페이지가 변경되었을 때 사용되는 함수.
  • defalutValue : 처음과 끝에서 항상 표시되는 페이지의 수.



데이터의 타입의 경우 아래와 같이 interface를 사용해 지정했다.

interface ProductListType {
  data: ProductType[];
  pageInfo: {
    page: number;
    size: number;
    totalElements: number;
    totalPages: number;
  };
}

interface ProductType {
  saleId: number;
  sellerId: number;
  productName: string;
  period: {
    startedAt: string;
    endAt: string;
  };
  isDeleted: boolean;
  isAlwaysOnSale: boolean;
  createdAt: string;
}



페이지네이션 라이브러리 적용은 어렵지 않았다.


처음 작성했던 코드는 value가 아니라 e.target.outerText 를 사용했었다. 그러다보니 -1를 줄여서 요청을 보낼 때 페이지 버튼을 누르면 정상적으로 작동했지만 양 옆의 < > 화살표 버튼을 누르면 e.target.outerTextNaN이 되어버려 제대로 작동되지 않았었는데 value를 사용해 손 쉽게 해결할 수 있었다.


profile
웹 개발자

0개의 댓글