Nextjs
2023-04-21 07:57
하기 이미지처럼 데이터를 한번에 보여주는 것이 아니라 페이지 번호로 나누어서 정해진 갯수만큼 보여준다

blog/index.js
const Homepage= ({ posts, numPages }) => {
return (
<Layout data={posts}>
<PostList data={posts} numPages={numPages} />
</Layout>
);
};
export default Homepage;
export async getStaticProps() {
const res = await fetch('https://...') // 데이터 가져오기
const allPosts = await res.json();
const postsPerPage = 6; // 한페이지에 몇 개의 컨텐츠를 보여줄건지 정의
const numPages = Math.ceil(allPosts.length / postsPerPage); // 총 페이지의 갯수
const posts = allPosts.slice(0, postsPerPage); // blog/index.js 는 첫 페이지를 의미한다
return {
props: {posts, numPages},
}
}
javascriptblog/[pageNumber].jsx
const Page = ({ posts, numPages }) => {
return (
<Layout data={posts}>
<PostList data={posts} numPages={numPages} />
</Layout>
);
};
export default Page;
// build시 생성할 파일 정의
export async function getStaticPaths() {
const res = await fetch('https://...') // 데이터 가져오기
const allPosts = await res.json();
const postsPerPage = 6; // 한페이지에 몇 개의 컨텐츠를 보여줄건지 정의
const numPages = Math.ceil(allPosts.results.length / postsPerPage); // 총 페이지의 갯수
const paths = [];
for (let i = 1; i <= numPages; i++) {
paths.push({ params: { pageNumber: i.toString() } });
}
return { paths, fallback: false };
}
// 위 코드에 의해 numPages가 3이라고 하면 blog/1, blog/2, blog/3 페이지 생성
export async function getStaticProps({ params }) {
const res = await fetch('https://...') // 데이터 가져오기
const allPosts = await res.json();
const postsPerPage = 6; // 한페이지에 몇 개의 컨텐츠를 보여줄건지 정의
const numPages = Math.ceil(allPosts.results.length / postsPerPage); // 총 페이지의 갯수
const offset = (params.pageNumber - 1) * postsPerPage;
const posts = allPosts.results.slice(offset, offset + postsPerPage);
return {
props: { posts, numPages },
};
}
javascriptcomponents/PostList
const PostList = ({ data, numPages }) => {
return (
<>
...
<PostPagination numPages={numPages} />
</>
)
}
javascriptcomponents/PostPagination
import styled from "@emotion/styled";
import { useRouter } from "next/router";
import { useState, useEffect } from "react";
export default function PostPagination({ numPages }) {
const router = useRouter();
const [page, setPage] = useState(1);
useEffect(() => {
setPage(router.query.pageNumber === undefined ? 1 : parseInt(router.query.pageNumber));
}, [router.query.pageNumber]);
const handlePrevClick = () => {
router.push(`/blog/${page - 1}`);
setPage(page - 1);
};
const handleNextClick = () => {
router.push(`/blog/${page + 1}`);
setPage(page + 1);
};
return (
<Base spacing={2}>
<Pagination>
<PrevBtn disabled={page === 1} onClick={handlePrevClick}>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="w-5 h-5">
<path fill-rule="evenodd" d="M12.79 5.23a.75.75 0 01-.02 1.06L8.832 10l3.938 3.71a.75.75 0 11-1.04 1.08l-4.5-4.25a.75.75 0 010-1.08l4.5-4.25a.75.75 0 011.06.02z" clip-rule="evenodd" />
</svg>
</PrevBtn>
{new Array(numPages).fill(0).map((v, i) => {
return (
<PaginationItem page={page === i + 1} key={i} onClick={(e) => router.push(`/blog/${e.target.innerText === "1" ? "" : e.target.innerText}`)}>
{i + 1}
</PaginationItem>
);
})}
<NextBtn disabled={page === numPages} onClick={handleNextClick}>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="w-5 h-5">
<path fill-rule="evenodd" d="M7.21 14.77a.75.75 0 01.02-1.06L11.168 10 7.23 6.29a.75.75 0 111.04-1.08l4.5 4.25a.75.75 0 010 1.08l-4.5 4.25a.75.75 0 01-1.06-.02z" clip-rule="evenodd" />
</svg>
</NextBtn>
</Pagination>
</Base>
);
}
const PaginationItem = styled.li`
background-color: ${({ page }) => (page ? "var(--purple-color)" : undefined)};
color: ${({ page }) => (page ? "#fff" : undefined)};
width: 30px;
height: 30px;
display: flex;
justify-content: center;
align-items: center;
padding: 5px;
border-radius: 50%;
`;
const PrevBtn = styled.li`
width: 25px;
height: 25px;
opacity: ${({ disabled }) => (disabled ? "0.2" : undefined)};
pointer-events: ${({ disabled }) => (disabled ? "none" : undefined)};
`;
const NextBtn = styled.li`
width: 25px;
height: 25px;
opacity: ${({ disabled }) => (disabled ? "0.2" : undefined)};
pointer-events: ${({ disabled }) => (disabled ? "none" : undefined)};
`;
javascript