[React] 페이지네이션 구현

zzincode·2024년 1월 25일
0

React

목록 보기
11/20
post-thumbnail

1. 라이브러리 사용

https://www.npmjs.com/package/react-js-pagination

$ npm install react-js-pagination

import { useState } from "react";
import data from "../src/utils/db.json";
import Pagination from "react-js-pagination";
import "./App.css";



function App() {
  const [page, setPage] = useState(1); //현재 페이지
  const [selected, setSelected] = useState(5); //한 페이지에 보여질 게시물 수
  const startIdx = (page - 1) * selected; //한 페이지의 첫 게시물 인덱스
  const endIdx = startIdx + selected; //한 페이지의 마지막 게시물 인덱스
  const paginatedList = data.slice(startIdx, endIdx);//한 페이지의 게시물들
  
  const handlePageChange = (page) => {
    setPage(page);
  }; 
  const handleSelect = (e) => {
    setSelected(Number(e.target.value));
    setPage(1);
  };

  
  return (
    <div className="App">
      <select onChange={handleSelect} value={selected}> //한 페이지에 보이는 게시물 갯수 지정
        {[5, 6, 7, 8, 9, 10].map((option) => (
          <option key={option} value={option}>
            {option}
          </option>
        ))}
      </select>
      <table>
        <thead>
          <tr>
            <td>
              <input type="checkbox" />
            </td>
            <th>No</th>
            <th>Title</th>
            <th>Date</th>
          </tr>
        </thead>
        <tbody>
          {paginatedList.map((data) => (
            <tr key={data.id}>
              <td>
                <input type="checkbox" />
              </td>
              <td>{data.id}</td>
              <td>{data.title}</td>
              <td>{data.date}</td>
            </tr>
          ))}
        </tbody>
      </table>
      <Pagination
        activePage={page}
        itemsCountPerPage={selected}
        pageRangeDisplayed={5}
        totalItemsCount={data.length}
        onChange={handlePageChange}
      />
    </div>
  );
}

export default App;

2. 라이브러리 없이

1. select(한 페이지에 보여지는 게시물 수)에 따라 페이지들을 pageIdx에 배열로 push한 후 map함수를 통해 출력

 const pageIdx = []; // 총 페이지들
  for (let i = 1; i <= pagingCount; i++) {
    pageIdx.push(i);
  }
...
{pageIdx.map((i) => (
          <li
            key={i}
            value={i}
            className={page === i && "active"}
          >
            {i}
          </li>
        ))}

2. 화살표 및 숫자를 눌렀을 때 해당 페이지로 넘어갈 수 있는 handlePageChange함수 생성

방법1)switch문을 활용하여 해당 버튼이 눌렸을 때 작동하도록 조건 나누기

const handlePageChange = (action) => {
    switch (action) {
      case "first":
        setPage(1);
        break;
      case "prev":
        if (page > 1) setPage(page - 1);
        break;
      case "next":
        if (page < pagingCount) setPage(page + 1);
        break;
      case "last":
        setPage(pagingCount);
        break;
      default:
        setPage(action.target.value);
        break;
    }
  };
...
      <ul>
        <li onClick={() => handlePageChange("first")}>⏪️</li>
        <li onClick={() => handlePageChange("prev")}>◀️</li>
        {pageIdx.map((i) => (
          <li
            key={i}
            value={i}
            onClick={(i) => handlePageChange(i)}
            className={page === i && "active"}
          >
            {i}
          </li>
        ))}
        <li onClick={() => handlePageChange("next")}>▶️</li>
        <li onClick={() => handlePageChange("last")}>⏩️</li>
      </ul>

방법2) if문 조건식(범위내에서 작동) + 매개변수(변경하려는 페이지 번호)

좀더 간단한 코드⭐️

const handlePageChange = (page) => {
    if (page >= 1 && page <= pagingCount) {
      setPage(page);
    }
  };
...
<ul>
        <li onClick={() => handlePageChange(1)}>⏪️</li>
        <li onClick={() => handlePageChange(page - 1)}>◀️</li>
        {pageIdx.map((i) => (
          <li
            key={i}
            onClick={() => handlePageChange(i)}
            className={page === i && "active"}
          >
            {i}
          </li>
        ))}
        <li onClick={() => handlePageChange(page + 1)}>▶️</li>
        <li onClick={() => handlePageChange(pagingCount)}>⏩️</li>
      </ul>

전체 코드

import { useState } from "react";
import data from "../src/utils/db.json";
import "./App.css";

function App() {
 
  const [selected, setSelected] = useState(5); // 한 페이지에 보여질 게시물 수
  const [page, setPage] = useState(1); // 현재 페이지
  const startIdx = (page - 1) * selected; // 한 페이지의 첫 게시물 인덱스
  const endIdx = startIdx + selected; // 한 페이지의 마지막 게시물 인덱스
  const paginatedList = data.slice(startIdx, endIdx); // 한 페이지의 게시물들
  const pagingCount = Math.ceil(data.length / selected); // 총 페이지 갯수
  const pageIdx = []; // 총 페이지들
  for (let i = 1; i <= pagingCount; i++) {
    pageIdx.push(i);
  }

  const handlePageChange = (page) => {
    if (page >= 1 && page <= pagingCount) {
      setPage(page);
    }
  };

  const handleSelect = (e) => {
    setSelected(Number(e.target.value));
    setPage(1);
  };

  return (
    <div className="App">
      <select onChange={handleSelect} value={selected}>
        {[5, 6, 7, 8, 9, 10].map((option) => (
          <option key={option} value={option}>
            {option}
          </option>
        ))}
      </select>
      <table>
        <thead>
          <tr>
            <td>
              <input type="checkbox" />
            </td>
            <th>No</th>
            <th>Title</th>
            <th>Date</th>
          </tr>
        </thead>
        <tbody>
          {paginatedList.map((data) => (
            <tr key={data.id}>
              <td>
                <input type="checkbox" />
              </td>
              <td>{data.id}</td>
              <td>{data.title}</td>
              <td>{data.date}</td>
            </tr>
          ))}
        </tbody>
      </table>
      <ul>
        <li onClick={() => handlePageChange(1)}>⏪️</li>
        <li onClick={() => handlePageChange(page - 1)}>◀️</li>
        {pageIdx.map((i) => (
          <li
            key={i}
            onClick={() => handlePageChange(i)}
            className={page === i && "active"}
          >
            {i}
          </li>
        ))}
        <input
          type="text"
          ref={pageRef}
          defaultValue={page}
          onKeyPress={(e) => {
            if (e.key === "Enter") {
              e.preventDefault();
              handlePageChange(pageRef.current.value);
            }
          }}
        />
        /{pagingCount}
        <li onClick={() => handlePageChange(page + 1)}>▶️</li>
        <li onClick={() => handlePageChange(pagingCount)}>⏩️</li>
      </ul>
    </div>
  );
}

export default App;

전체 코드

import { useState } from "react";
import data from "../src/utils/db.json";
import "./App.css";

function App() {
  const [selected, setSelected] = useState(5); // 한 페이지에 보여질 게시물 수
  const [page, setPage] = useState(1); // 현재 페이지
  const startIdx = (page - 1) * selected; // 한 페이지의 첫 게시물 인덱스
  const endIdx = startIdx + selected; // 한 페이지의 마지막 게시물 인덱스
  const paginatedList = data.slice(startIdx, endIdx); // 한 페이지의 게시물들
  const pagingCount = Math.ceil(data.length / selected); // 총 페이지 갯수
  const pageIdx = []; // 총 페이지들
  for (let i = 1; i <= pagingCount; i++) {
    pageIdx.push(i);
  }

  const handlePageChange = (page) => {
    if (!isNaN(page) && page >= 1 && page <= pagingCount) {
      setPage(page);
    } else {
      alert("범위 내의 숫자를 입력하세요");
    }
  };

  const handleSelect = (e) => {
    setSelected(Number(e.target.value));
    setPage(1);
  };

  return (
    <div className="App">
      <select onChange={handleSelect} value={selected}>
        {[5, 6, 7, 8, 9, 10].map((option) => (
          <option key={option} value={option}>
            {option}
          </option>
        ))}
      </select>
      <table>
        <thead>
          <tr>
            <td>
              <input type="checkbox" />
            </td>
            <th>No</th>
            <th>Title</th>
            <th>Date</th>
          </tr>
        </thead>
        <tbody>
          {paginatedList.map((data) => (
            <tr key={data.id}>
              <td>
                <input type="checkbox" />
              </td>
              <td>{data.id}</td>
              <td>{data.title}</td>
              <td>{data.date}</td>
            </tr>
          ))}
        </tbody>
      </table>
      <ul>
        <li onClick={() => handlePageChange(1)}>⏪️</li>
        <li onClick={() => handlePageChange(page - 1)}>◀️</li>
        <li>
          {pageIdx.map((i) => (
          <li
            key={i}
            onClick={() => handlePageChange(i)}
            className={page === i && "active"}
          >
            {i}
          </li>
        ))} 
        </li>
        <li onClick={() => handlePageChange(page + 1)}>▶️</li>
        <li onClick={() => handlePageChange(pagingCount)}>⏩️</li>
      </ul>
    </div>
  );
}

export default App;

0개의 댓글