sns 프로젝트

페이지네이션 기능 구현하기

우주속공간 2024. 1. 22. 17:14

 

 

📁 페이지네이션 기능  미리보기

 

 

 

 

 

페이지네이션 기능 구현 과정을 간단하게 정리해보자면 다음과 같다.

 

프론트

  • 페이지네이션 bar 만들기
➡️ Math.ceil 사용 (총게시물수/postPerPage)만큼 for문 돌려서 pageNumber 배열에 추가
➡️ pageNumber map 돌려서 bar 생성
➡️ 원하는 숫자를 클릭하면 현재 페이지를 나타내는 currentPage 상태가 업데이트(dispatch)되고 새로운 데이터를 가져옴(invalidateQueries) 

 

 

백엔드

  • 백엔드 getTweet API 수정(limit, offset 설정)
➡️ limit - 한번에 몇개씩 가져올건지 설정, offset : 몇번째부터 가져올건지 설정(10개로 설정)
➡️ 현재 페이지 숫자 pageNum을 가져와서 offset으로 몇번째 데이터부터 가져올지 설정

 

 

 

 

실제 구현한 코드


 

getTweets.ts

 

limit - 한번에 몇개씩 가져올건지 설정, offset : 몇번째부터 가져올건지 설정

 

데이터를 받아올때 한번에 10개씩 가져올 수 있도록 limit 설정

현재 페이지 숫자 pageNum을 가져와서 offset으로 몇번째 데이터부터 가져올지 설정

 


router.get(
  "/top",
  verifyRefreshToken,
  async (req: any, res: Response, next: NextFunction) => {
    let pageNum = Number(res.req.query.currentPage); // 요청 페이지 넘버

    let offset = 0;
    if (pageNum > 1) {
    
    // 몇번째부터 가져올지 계산
    
      offset = 10 * (pageNum - 1);
    }

    const { search } = res.req.query;
    let count = await Tweets.count({
      where: {
        [Op.or]: [
          { content: { [Op.like]: [`%${search}%`] } },
          { tag: { [Op.like]: [`%${search}%`] } },
        ],
      },
    });

    const currentUser: Users[] = await Users.findOne({
      where: {
        email: req.email,
      },
    }).then((r: any) => {
      return r.user_id;
    });
    const topUser = await Tweets.findAll({
      include: [Likes, Comments],
      offset: offset,
      
	//limit 설정
    
      limit: 10,
      where: {
        [Op.or]: [
          { content: { [Op.like]: [`%${search}%`] } },
          { tag: { [Op.like]: [`%${search}%`] } },
        ],
      },

	// 아래 getTweet API코드와 동일

 

https://github.com/goops2000/My-Nwitter-Backend

 

GitHub - goops2000/My-Nwitter-Backend

Contribute to goops2000/My-Nwitter-Backend development by creating an account on GitHub.

github.com

 

 

Pagination 컴포넌트

 

➡️ Math.ceil 사용 (총게시물수/postPerPage)만큼 for문 돌려서 pageNumber 배열에 추가
➡️ pageNumber map 돌려서 bar 생성
➡️ 원하는 숫자를 클릭하면 현재 페이지를 나타내는 currentPage 상태가 업데이트(dispatch)되고 새로운 데이터를 가져옴(invalidateQueries) 

import React, { useState } from "react";
import { useQueryClient } from "react-query";
import { useDispatch } from "react-redux";
import { useSelector } from "react-redux";
import {
  changeCurrentPage,
  setPageCount,
} from "../../redux/createSlice/GetDataSlice";
import { RootState } from "../../redux/store";

const Pagination = ({ count }: any) => {
  const pageNumber = [];
  const dispatch = useDispatch();
  const postPerPage = 10;
  const queryClient = useQueryClient();

  const data: any = queryClient.getQueryData(["selectData"]);

  const currentPage = useSelector(
    (state: RootState) => state.getData.currentPage
  );

//Math.ceil 사용 (총게시물수/postPerPage)만큼 for문 돌려서 pageNumber 배열에 추가

// 몇페이지까지 있는지 보여주기

  for (let i = 1; i <= Math.ceil(count / postPerPage); i++) {
    pageNumber.push(i);
  }

  return (
    <div className="flex justify-items-center border-t   ">
      <div className="flex flex-1 w-full justify-center ">
        <nav
          className="isolate inline-flex -space-x-px rounded-md shadow-sm"
          aria-label="Pagination"
        >
        
       // pageNumber map 돌려서 bar 생성
       
          {pageNumber.map((number) => (
            <div
              aria-current="page"
              className="relative inline-flex items-center border rounded-lg border-gray-300  bg-white px-4 py-2 text-sm  font-bold font-mono text-gray-500 hover:bg-gray-50 focus:z-20"
              key={number}
              onClick={() => {
             
              //원하는 숫자를 클릭하면 현재 페이지를 나타내는 currentPage 상태가 업데이트(dispatch)되고 새로운 데이터를 가져옴
              
                dispatch(changeCurrentPage(number));
                queryClient.invalidateQueries(["selectExploreData"]);
              }}
            >
              {number}
            </div>
          ))}
        </nav>
      </div>
    </div>
  );
};
export default Pagination;