게시글이 한 줄에 3개씩 3열이 있도록 게시글이 나열될 수 있도록 구현할 것이다
- mui Grid 활용
- mui Pagination 활용
<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>
spacing: 그리드 아이템 사이의 간격을 설정
=> 가장 작은 화면 크기(xs)에서는 아이템 사이의 간격을 2로 설정
=> 중간 화면 크기(md)에서는 간격을 3으로 설정
columns: 그리드 컨테이너의 열(column) 개수를 지정
=> 가장 작은 화면 크기(xs)에서는 컨테이너가 4개의 열로 구성
=> 중간 화면 크기(sm)에서는 8개의 열로 구성
=> 큰 화면 크기(md)에서는 12개의 열로 구성
xs와 sm, md 에 따른 아이템이 한 행에 몇 개의 열로 구성될 지를 지정
각각의 크기일 때 아이템이 4개의 열을 차지하도록 구성
따라서,
md일때 열이 12개 중 item이 4를 차지하므로 한 행에 3개의 아이템이 나열됨
sm일 때 열이 8개 중 item이 4를 차지하므로 한 행에 2개의 아이템이 나열됨
xs일 때 열이 4개 중 item이 4를 차지하므로 한 행에 1개의 아이템이 나열됨
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>
);