[mui]페이지 네이션 구현

hansoom·2023년 7월 7일
0

React

목록 보기
11/13
post-thumbnail

mui pagination

게시글이 한 줄에 3개씩 3열이 있도록 게시글이 나열될 수 있도록 구현할 것이다

  1. mui Grid 활용
  2. mui Pagination 활용

1. mui Grid 태그

<Grid
  container
  spacing={{ xs: 2, md: 3 }}
  columns={{ xs: 4, sm: 8, md: 12 }}
>
   {Array.from(Array(itemCount))
   .map((_, index) => (
   <Grid item xs={4} sm={4} md={4} key={index}>
      <Post />
   </Grid>
))}
</Grid>
  • Grid container

spacing: 그리드 아이템 사이의 간격을 설정
=> 가장 작은 화면 크기(xs)에서는 아이템 사이의 간격을 2로 설정
=> 중간 화면 크기(md)에서는 간격을 3으로 설정

columns: 그리드 컨테이너의 열(column) 개수를 지정
=> 가장 작은 화면 크기(xs)에서는 컨테이너가 4개의 열로 구성
=> 중간 화면 크기(sm)에서는 8개의 열로 구성
=> 큰 화면 크기(md)에서는 12개의 열로 구성

  • Grid item

xs와 sm, md 에 따른 아이템이 한 행에 몇 개의 열로 구성될 지를 지정
각각의 크기일 때 아이템이 4개의 열을 차지하도록 구성

따라서,
md일때 열이 12개 중 item이 4를 차지하므로 한 행에 3개의 아이템이 나열됨
sm일 때 열이 8개 중 item이 4를 차지하므로 한 행에 2개의 아이템이 나열됨
xs일 때 열이 4개 중 item이 4를 차지하므로 한 행에 1개의 아이템이 나열됨

2. mui Pagination 컴포넌트

const itemCount = 10; 
const itemsPerPage = 9;

총 post의 총 개수를 itemCount 변수에 저장한다.
페이지 네이션 한 페이지 당 보여질 아이템의 개수를 변수 itemsPerPage 변수에 저장한다.

const pageCount = Math.ceil(itemCount / itemsPerPage)

필요한 페이지의 개수를 변수에 따로 저장해둔다.

const startIndex = currentPage * itemsPerPage;
const endIndex =
    (currentPage + 1) * : itemsPerPage;

해당 페이지에 보여질 첫번째 아이템의 index와 해당 페이지에 보여질 마지막 아이템의 index를 따로 변수에 저장한다.

const [currentPage, setCurrentPage] = useState(0);

클릭할 때마다 페이지 값이 변화하는 것을 인지하기 위해 해당 페이지의 값을 state로 생성한다.

<Grid
        container
        spacing={{ xs: 2, md: 3 }}
        columns={{ xs: 4, sm: 8, md: 12 }}
      >
        {Array.from(Array(itemCount))
          .slice(startIndex, endIndex)
          .map((_, index) => (
            <Grid item xs={4} sm={4} md={4} key={index}>
              <RecruitmentPost />
            </Grid>
          ))}
</Grid>
{pageCount > 1 && (
        <Pagination
          count={pageCount}
          page={currentPage + 1}
          onChange={(event, page) => setCurrentPage(page - 1)}
          size="small"
        />
)}

해당 Grid에 배열을 slice로 앞에서 정의해둔 start index, end index 로 잘라서 보여질 수 있도록 한다.

통신으로 페이지네이션 구현 코드

  // 반응형 처리를 위해 추가
 const isMobile = useMediaQuery("(max-width:900px)");
  // 현재 페이지
  const [currentPage, setCurrentPage] = useState(0);
  // 모바일일 경우에 한페이지에 6개씩 보여주고 웹일 경우 9개씩 보여지게 하기
  const itemsPerPage = isMobile ? 6 : 9;

  // 총 게시글 개수
  let itemCount = 0;
  // 총 페이지 개수
  let pageCount = 0;

  // 모집글 리스트 조회하는 함수
  const { data, isLoading } = useQuery(
    ["allRecruitmentPosts", currentPage],
    // 현재 페이지와 페이지에 보여질 게시글 개수 전달
    () => getAllRecruitmentPost(currentPage + 1, itemsPerPage)
  );
  if (data && !isLoading) {
    itemCount = data.totalElements;
    pageCount = Math.ceil(itemCount / itemsPerPage);
  }

  return (
    <div className="recruitment">
      <Grid
        container
        spacing={{ xs: 2, md: 3 }}
        columns={{ xs: 4, sm: 8, md: 12 }}
      >
        {!isLoading &&
          data?.content.map((content, index) => (
            <Grid item xs={4} sm={4} md={4} key={index}>
              <RecruitmentPost data={content} />
            </Grid>
          ))}
      </Grid>
      {pageCount > 0 && (
        <Pagination
          count={pageCount}
          page={currentPage + 1}
          onChange={(event, page) => setCurrentPage(page - 1)}
        />
      )}
    </div>
  );

0개의 댓글