pagination 구현

Creating the dots·2021년 12월 6일
0

project-3-ShallWeHealth

목록 보기
17/26

구현방법1

깃헙링크

클라이언트에서 전체 데이터 한번에 받아서 페이지 누를때마다 다른 데이터 보여주기

  • useEffect로 한번에 모든 데이터 다 받아오기
  • 페이지를 누를때마다, 저장된 데이터를 10개씩(postPerPage) 보여준다
//App.js
import { useState, useEffect } from "react";
import axios from "axios";
import Post from "./Post";
import Pagination from "./Pagination";

function App() {
  const [posts, setPosts] = useState([]); //받아온 전체 데이터 저장
  const [currentPage, setCurrentPage] = useState(1); //현재 페이지는 1로 기본설정
  const [postPerPage, setPostPerPage] = useState(10); //한페이지에 10개의 데이터 보여주기

  useEffect(() => {
    const fetchPosts = async () => {
      const res = await axios.get("https://jsonplaceholder.typicode.com/posts");
      setPosts(res.data); //모든 데이터가 posts에 저장됨
    };
    fetchPosts();
  }, []);

  let indexOfLastPost = currentPage * postPerPage; //보여줄 마지막 데이터의 인덱스  
  let indexOfFirstPost = indexOfLastPost - postPerPage; //보여줄 첫번째 데이터의 인덱스 
  let currentPosts = posts.slice(indexOfFirstPost, indexOfLastPost); //indexOfFirstPost번째부터 indexOfLastPost-1까지
  const paginate = (pageNum) => setCurrentPage(pageNum); //현재 페이지를 변경하는 함수 
  
  return (
    <div>
      <h2>My Blog Title</h2>
      <Post posts={currentPosts} />
      <Pagination
        postPerPage={postPerPage}
        totalPosts={posts.length}
        paginate={paginate}
      />
    </div>
  );
}

export default App;

//Post.js
const Post = ({ posts }) => {
  return (
    <ul>
      {posts.map((post) => (
        <li key={post.id}>{post.title}</li>
      ))}
    </ul>
  );
};
export default Post;

//Pagination.js
const Pagination = ({ postPerPage, totalPosts, paginate }) => {
  const pageNumbers = [];

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

  return (
    <nav>
      <ul>
        {pageNumbers.map((num) => (
          <li key={num}>
            <a onClick={() => paginate(num)} href="!#">
              {num}
            </a> 
          </li>
        ))}
      </ul>
    </nav>
  );
};
export default Pagination;

구현방법2

클라이언트에서 page를 query로 보내면 서버에서 그에 맞는 데이터 보내주기

  • 모집게시판과 관리자페이지에 페이지네이션 사용
  • DB에서 가져오는 총 데이터의 개수를 알아야 페이지네이션에 마지막 페이지 숫자를 설정할 수 있다
  • 한 페이지에 몇개의 데이터를 보여줄지 알아야한다
  • 현재 몇 페이지인지 알아야한다.
  • <,> 버튼클릭시 이전, 다음 페이지로 이동
    • 현재 페이지가 첫페이지이거나 마지막 페이지인 경우, 서버에 요청보내지 않는다.
  • <<,>> 버튼 클릭시 처음, 마지막 페이지로 이동
    • 현재 페이지가 첫페이지이거나 마지막 페이지인 경우, 서버에 요청보내지 않는다.
//Pagination.js 페이지네이션 컴포넌트
import './Pagination.css'; 

const Pagination = ({
  activePage,
  itemsCountPerPage,
  totalItemsCount,
  pageRangeDisplayed,
  paginate
}) => {
  const pageNumbers = [];
  const toalPages = Math.ceil(totalItemsCount/itemsCountPerPage);
  const maxPage = pageRangeDisplayed; 
  let pages = 0;
  if(totalPages < maxPage) {
    //5페이지까지 최대로 띄울 수 있는데 3페이지까지만 필요한 경우 
    pages = totalPage;
  }else{
    pages = maxPage;
  }
  
  for(let i=1; i<=pages; i++){
    pageNumbers.push(i);
  }
  return (
    <>
    <div className='pagination-container'>
      <span
       className='first'
       style={{ color: '#C4C4C4', fontWeight: 'bold'}}
       onClick={() => {activePage > pageRangeDisplayed ? paginate(activePage - pageRangeDisplayed : paginate(1)}}
      >&lt;&lt;
      </span>
      <span
      className='prev'
      style={{ color: '#C4C4C4', fontWeight: 'bold' }}
      onClick={() => {
        activePage > 1 ? paginate(activePage - 1) : paginate(activePage);
      }}
        >&lt;
      </span>
      <ul className='paging-group'>
        {pageNumbers.map((num) => {
          return (
            <li key={num} className={activePage === num? 'active' : ''}>
              <span className='paging-num' onClick={()=> paginate(num)}>
                {num}
              </span>
            </li>
	</ul>
        <span
        className='next'
        style={{ color: '#C4C4C4', fontWeight: 'bold' }}
        onClick={() => {
          activePage < totalPage
            ? paginate(activePage + 1)
          : paginate(activePage);
        }}
          >&gt;
        </span>
        <span
        className='last'
        style={{ color: '#C4C4C4', fontWeight: 'bold' }}
        onClick={() => paginate(totalPage)}
          >&gt;&gt;
        </span>
    </div>
    </>
  )
};
export default Pagination;

//postList.js 
/*서버에서는 sequelize를 사용해서 findAndCountAll을 쓸 경우, 
offest, limit을 설정해서 전달할 수 있다.
즉, 서버에서는 req.query로 전달받은 page와 설정된 limit에 따라 약속된 만큼의
데이터와 총 데이터 개수를 전달한다.
*/
const { page, nickname } = req.query;
const limit = 7;
const offset = (page - 1) * limit;
//이하 생략
const { count, rows } = await Post.findAndCountAll({
  where: {
    [Op.or]: [
      { hostId: data1.dataValues.id },
      { guestId: data1.dataValues.id },
    ],
  },
  include: [
    { model: User, as: "guests", attributes: ["nickname"] },
    { model: User, as: "hosts", attributes: ["nickname"] },
  ],
  offset,
  limit,
  order: [["createdAt", "ASC"]],
});

위와 같이 구현시, 페이징 넘기는 기능(이전, 다음 버튼클릭)이 없어 추가해 블로깅해두었습니다

페이징 오류 해결 확인하러가기

profile
어제보다 나은 오늘을 만드는 중

0개의 댓글