[React] 페이지네이션의 맛

Jin·2024년 5월 17일
1
post-thumbnail

환경
React
JavaScript
shadcn/ui
tailwind css


Vue가 아닌 React로 돌아왔다.

페이지네이션만 세 번이나 주저리거렸다.

왜일까하니

CRUD수준에서 어려운 부분을 꼽으라면
1. 수정 (프론트 구현이 비교적 어려움)
2. 페이지네이션 (백엔드도 직접 구현하면 생각 좀 해야함 + 프론트 또한...)
이기 때문이다.

✨필요한 것

나의 멋진 백엔드 코드

✨내가 원했던 것

  1. 5개의 페이지만 띄워줄 것
  2. 5페이지 이상이면 6~10페이지 띄워줄 것
  3. prev누르면 -5페이지, next누르면 +5페이지

✨참고할 것

https://ui.shadcn.com/docs/components/pagination

✨설치

npx shadcn-ui@latest add pagination

✨넘어오는 데이터

{
    "items": [
        {
            "id": 1,
            "title": "1",
            "content": "1",
            "author": "1",
            "password": "1",
            "comments": [],
            "date": "2024-05-16 22:13:38.212614"
        }
    ],
    ... 생략
    ,
    "total": 17,
    "page": 2,
    "size": 15,
    "pages": 2
}

total: 총 게시글의 개수
page: 현재 페이지
pages: 총 페이지
size: 한 번에 보여줄 페이지

✨코드

import {
  Pagination,
  PaginationContent,
  PaginationEllipsis,
  PaginationItem,
  PaginationLink,
  PaginationNext,
  PaginationPrevious,
} from "@/components/ui/pagination";
... 생략

function post(){
    const [posts, setPosts] = useState([]);
  const [currentPage, setCurrentPage] = useState(1); // 현재 페이지 상태 추가
  const [totalPages, setTotalPages] = useState(0);
  const [pageRangeStart, setPageRangeStart] = useState(1);
}
  const updatePageRange = (newCurrentPage) => {
    const newStartPage = Math.floor((newCurrentPage - 1) / 5) * 5 + 1;
    if (newStartPage !== pageRangeStart) {
      setPageRangeStart(newStartPage);
    }
  };
  useEffect(() => {
    fetchPosts();
  }, []); // 컴포넌트 마운트 시 첫 페이지의 게시물을 가져옵니다.

  const fetchPosts = async (page = 1) => {
    const response = await axios.get(
      `http://localhost:8000/post/posts?page=${page}`
    );
    setPosts(response.data.items);
    setCurrentPage(page); // 페이지를 성공적으로 불러온 후 현재 페이지 상태 업데이트
    setTotalPages(response.data.pages);
    updatePageRange(page); // 페이지 업데이트 함수에 현재 페이지 전달
  };

return(
		... 게시판 목록관련 ...
        <div>
        <Pagination>
          <PaginationContent>
            <PaginationItem>
              <PaginationPrevious
                onClick={() => fetchPosts(Math.max(currentPage - 5, 1))}
                disabled={currentPage - 5 < 1}
                style={{ cursor: "pointer" }}
              />
            </PaginationItem>
            {[...Array(5)].map((_, index) => {
              const pageNumber = pageRangeStart + index;
              return pageNumber <= totalPages ? (
                <PaginationItem key={pageNumber}>
                  <PaginationLink
                    onClick={() => fetchPosts(pageNumber)}
                    style={{
                      backgroundColor:
                        pageNumber === currentPage ? "#fff" : "#fff", // 이 부분 바꾸면 색바뀜
                      color: pageNumber === currentPage ? "#fff" : "#fff", // 여기도
                      cursor: "pointer",
                    }}
                  >
                    {pageNumber}
                  </PaginationLink>
                </PaginationItem>
              ) : null;
            })}
            <PaginationItem>
              <PaginationNext
                onClick={() =>
                  fetchPosts(Math.min(currentPage + 5, totalPages))
                }
                disabled={currentPage + 5 > totalPages}
                style={{ cursor: "pointer"}}
              />
            </PaginationItem>
          </PaginationContent>
        </Pagination>
      </div>
... 생략

);

✨결과


+) 게시글 잘 넘어감..

profile
go-getter

2개의 댓글

comment-user-thumbnail
2024년 6월 15일

이제 깃허브에 html, css, react 추가해주세요 ㅋ ㅋ

1개의 답글