Pagination

dang2·2023년 7월 13일
1

React

목록 보기
3/5

페이지네이션이란?

페이지네이션은 일반적으로 많은 수의 결과 또는 항목을 관리하기 위해 디지털 콘텐츠를 여러 페이지로 분할하는 프로세스를 의미한다. 예를 들어, 웹 사이트에서 사영자가 검색을 수행하고 수백 또는 수천개의 결과가 반환되면 이러한 결과는 페이지네이션을 사용하여 조직적이고 효율적으로 표시될 수 있다.

각 페이지에는 일반적으로 일정 수의 결과가 포함되며, 사용자는 ‘다음’,’첫페이지’, ‘마지막페이지’와 같은 컨트롤을 사용하여 다른 페이지로 이동할 수 있다. 페이지네이션은 사용자 경험을 향상시키고, 웹 사이트나 어플리케이션의 성능을 향상시키며, 부하를 줄이는데 도움이 된다.

페이지네이션을 위한 상태 설정

우선, 현재페이지와 페이지당 게시글 수를 정의하기 위한 상태를 정의한다.

currentPage는 현재 페이지 번호를 나타내며, postPerPage는 한 페이지에 보여줄 게시글의 수를 나타낸다.

const [ currentPage, setCurrentPage] = useState(1) 
const [ postPerPage, setPostPerPage] = useState(5)

현재 페이지의 게시글 선택하기

다음으로, 현재 페이지에 해당하는 게시글만 선택해야한다.

우리가 페이징을 적용하고자 하는 배열이 있다고 가정해보자. 예를 들어 20개의 게시글이 있는 배열이라면, 그 인덱스는 0~19까지 이루어져 있을 것이다. 이 배열을 페이지 별로 잘라서 보여주기 위해 우리는 각 페이지에서 가장 처음과 마지막에 해당하는 인덱스를 알아야 한다. 위의 코드에서 우리는 현재페이지를 currentPage, 표시할 게시물의 수를 postPerPage로 정의하였으며, 이를 바탕으로 각 페이지에서 마지막 게시물의 인덱스와 첫 게시물의 인덱스를 계산하게 된다.

// 현재 페이지의 마지막 게시글의 인덱스를 계산한다 
  // 예: currentPage가 1이고, postPerPage가 5라면, indexOfLastPost는 1 * 5 = 5
  const indexOfLastPost = currentPage * postPerPage 

  // 현재 페이지의 첫 게시글의 인덱스를 계산
  // 예: indexOfLastPost가 5이면, indexOfFirstPost는 5 - 5 = 0
  const indexOfFirstPost = indexOfLastPost - postPerPage

이렇게 계산한 indexOfFirstPost와 indexOfLastPost를 이용하여, 원본 배열에서 현재 페이지에 해당하는 게시글만 선택하게 된다. 이를 위해서 배열의 slice 함수를 이용한다. slice는 첫번째 인자로 받은 배열의 인덱스부터 마지막 인자로 받은 인덱스 -1 까지 원본 배열에서 잘라내어 반환한다.

//현재 페이지에 표시할 게시글만을 포함하는 배열
const currentPosts = result.slice(indexOfFirstPost, indexOfLastPost)

Pagination

이 컴포넌트는 페이지 번호를 클릭하면 paginate 함수를 실행하여 현재 페이지 번호를 업데이트한다.

  • totalPosts : 웹 페이지에 표시할 총 게시글의 수
  • postPerPage : 한페이지에 표시할 게시글의 수

totalPost / postsPerpage 는 총페이지 수를 계산하는데 사용된다.

예를 들어 총 게시글의 수가 100개이고, 한 페이지에 10개의 게시글을 표시하고 싶다면 totalPost / postsPerpage 는 100 / 10 = 10 이 되어 총 페이지 수는 10페이지가 된다. 그러나 만약 105개의 경우라면 , 실제 페이지의 수는 11 페이지가 되어야 한다.

따라서 Math,ceil 함수를 사용하여 결과를 올림하면, 총 페이지 수를 정확히 계산할 수 있다.

'use client'

export default function Pagination({ postsPerPage, totalPosts, paginate }){

  // 페이지 번호를 저장할 빈 배열을 선언
  const pageNumbers = [];

  // 총 페이지 수를 계산하고, 각 페이지 번호를 pageNumbers 배열에 추가
// ex) Math,ceil(10.5) =11 
  for(let i = 1; i <= Math.ceil(totalPosts / postsPerPage); i++){
    pageNumbers.push(i)
  }

  return (
    <nav>
      <ul className="pagination">
        {pageNumbers.map((number)=>(
          <li key={number} className="page-item">
             {/* 각 페이지 번호를 클릭하면 해당 페이지의 게시글을 보여주도록 paginate 함수를 실행 */}
            <a href="#" className="page-link" onClick={() => paginate(number)}>
              {number}
            </a>
          </li>
        ))}
      </ul>
    </nav>
  )
}

페이지 이동하기

그리고 유저가 다른 페이지 번호를 클릭하면 해당 페이지의 게시글을 보여주어야 한다. 이를 위해서 paginate 함수를 정의하여 setCurrentPage를 호출한다.

const paginate = (pageNumber) => setCurrentPage(pageNumber)

진행하던 미니 프로젝트에 실제로 적용시켜본 예시이다.

'use client'

import Link from "next/link"
import { useEffect, useState } from "react"
import Pagination from "./Pagination"

export default function ListItem({result}){


  const [ currentPage, setCurrentPage] = useState(1) 

  const [ postPerPage, setPostPerPage] = useState(5) 

  const indexOfLastPost = currentPage * postPerPage 

  
  const indexOfFirstPost = indexOfLastPost - postPerPage 

  const currentPosts = result.slice(indexOfFirstPost, indexOfLastPost) 


  const paginate = (pageNumber) => setCurrentPage(pageNumber)
  

  return (
    <>
    <div>
    {
      // currentPosts 배열을 순회하면서 각 게시글을 표시
      currentPosts.map((ele, idx) =>
        <div className="list-item" key={idx}>

          <Link prefetch={false} href={'/detail/' + ele._id}> 
            <h4>{ele.title}</h4>
          </Link>

       
          <Link href={'/edit/' + currentPosts[idx]._id}>🏏</Link>
        </div>
      )
    }
    </div>

    <Pagination postsPerPage={postPerPage} totalPosts={result.length} paginate={paginate}/>
    </>
  )
}

0개의 댓글

관련 채용 정보