[React] 부트스트랩 페이징 구현하기
본문 바로가기
더 알아보기/기능

[React] 부트스트랩 페이징 구현하기

by 은돌1113 2022. 4. 11.
 

Bootstrap 4 / Pagination / 이전 또는 다음 페이지로 연결하는 링크 꾸미기

글이 많을 때 다음 글 또는 이전 글, 다음 글 목록 또는 이전 글 목록으로 이동하는 링크를 만듭니다. 이를 페이지네이션(Pagination)이라고 하는데, Bootstrap에서는 페이지네이션을 쉽게 꾸밀 수 있

www.codingfactory.net

위 블로그의 기본 코드를 참고하여 구현하였다.

<ul class="pagination">
    <li class="page-item"><a class="page-link" href="#">Previous</a></li>
    <li class="page-item"><a class="page-link" href="#">1</a></li>
    <li class="page-item"><a class="page-link" href="#">2</a></li>
    <li class="page-item"><a class="page-link" href="#">3</a></li>
    <li class="page-item"><a class="page-link" href="#">4</a></li>
    <li class="page-item"><a class="page-link" href="#">5</a></li>
    <li class="page-item"><a class="page-link" href="#">Next</a></li>
</ul>

1. Paging.js라는 파일을 생성 후 컴포넌트를 하나 만들어 준다.

( + react의 useState, useEffect / styled-components import 해주기 )

import { useState, useEffect } from "react";
import styled from "styled-components";

const Paging2 = (props) => {
  return <div></div>;
};

export default Paging2;

 

2. 상단에 있는 ul/li 코드를 return 부분에 삽입 해준다.

더보기
import { useState, useEffect } from "react";
import styled from "styled-components";

const Paging2 = (props) => {
  return (
    <CSS>
      <ul class="pagination">
        <li class="page-item">
          <a class="page-link" href="#">
            Previous
          </a>
        </li>
        <li class="page-item">
          <a class="page-link" href="#">
            1
          </a>
        </li>
        <li class="page-item">
          <a class="page-link" href="#">
            2
          </a>
        </li>
        <li class="page-item">
          <a class="page-link" href="#">
            3
          </a>
        </li>
        <li class="page-item">
          <a class="page-link" href="#">
            4
          </a>
        </li>
        <li class="page-item">
          <a class="page-link" href="#">
            5
          </a>
        </li>
        <li class="page-item">
          <a class="page-link" href="#">
            Next
          </a>
        </li>
      </ul>
    </CSS>
  );
};

const CSS = styled.div`
`;

export default Paging2;

 

3. useState와 useEffect를 사용하여 페이지를 누를 때마다 페이지가 이동 될 수 있도록 코드를 수정한다.

- page, end state를 각각 생성한다. (page : 기본값은 1로 설정, 현재 페이지, end : 마지막 페이지)

- a 태그를 p 태그로 변경 시킨다. (안해도 무관하다)

- li 태그에 onClick 함수를 사용하여 page state를 변경 시킨다.

- li 태그의 className에 조건을 추가한다.

화살표를 누르면 page state의 값이 바뀌면서 active도 이동하게 된다.

더보기
import { useState, useEffect } from "react";
import styled from "styled-components";

const Paging2 = (props) => {
  const [page, setPage] = useState(1);
  const [end, setEnd] = useState(3);

  return (
    <CSS>
      현재 페이지 : {page}
      <br />
      <ul class="pagination">
        <li
          class="page-item"
          onClick={() => {
            setPage(page - 1);
          }}
        >
          <p className="page-link">{`<`}</p>
        </li>
        <li
          class={`page-item ${page === 1 ? "active" : undefined}`}
          onClick={() => {
            setPage(1);
          }}
        >
          <p className="page-link">1</p>
        </li>
        <li
          class={`page-item ${page === 2 ? "active" : undefined}`}
          onClick={() => {
            setPage(2);
          }}
        >
          <p className="page-link">2</p>
        </li>
        <li
          class={`page-item ${page === 3 ? "active" : undefined}`}
          onClick={() => {
            setPage(3);
          }}
        >
          <p className="page-link">3</p>
        </li>
        <li
          class="page-item"
          onClick={() => {
            setPage(page + 1);
          }}
        >
          <p className="page-link">{`>`}</p>
        </li>
      </ul>
    </CSS>
  );
};

const CSS = styled.div`
  margin-top: 20px;
  margin-left: 20px;
`;

export default Paging2;

 

4. CSS에 들어가기 전에 예외 처리를 해준다.

 

1) 첫 페이지(page)에 1, 마지막 페이지(end)를 넘어가는 경우가 생긴다.

화살표 onClick 함수에 조건문을 추가하여 첫 페이지이거나 마지막 페이지라면 page state를 변경 시키지 않도록 한다.

더보기
<li
  class="page-item"
  onClick={() => {
    if (page <= 1) {
      console.log("첫 페이지");
    } else {
      setPage(page - 1);
    }
  }}
>
  <p className="page-link">{`<`}</p>
</li>
<li
  class="page-item"
  onClick={() => {
    if (page >= end) {
      console.log("마지막 페이지");
    } else {
      setPage(page + 1);
    }
  }}
>
  <p className="page-link">{`>`}</p>
</li>

 

+ 4-2부터는 페이지가 늘어나기 때문에 <, >를 제외한 가운데 부분!! 숫자 부분을 .map을 사용하는 코드로 변경한다.

 

2) 5 페이지씩 끊어서 보여주고 싶은 경우

Array.from({ length: end }, (x, i) => i + 1)

Array.from을 사용하여 페이지 개수만큼 배열을 만들고, 기본 값으로는 i+1을 넣는다.

(end의 기본 값을 20으로 늘린다.)

 

그 후 useEffect를 사용하여 page state의 값이 바뀔 때마다

콜백함수가 실행 될 수 있도록 설정하고, 아래 코드를 삽입한다.

(위 코드에서 initial_pagign 상수를만든 이유이기도 하다. paging state에서 배열을 만들고 setPaging으로 값을 변경 시

기존 배열을 매번 생성 해줘야 하는 데 이 배열은 한번 선언되면 변경 하지 않기 때문에 const를 사용했다.

즉, 값이 변경 되지 않기 때문에 const로 배열 생성함)

  useEffect(() => {
    if (page > 0 && page <= 5) {
      setPaging(initial_paging.slice(0, 5));
    } else if (page > 5 && page <= 10) {
      setPaging(initial_paging.slice(5, 10));
    } else if (page > 10 && page <= 15) {
      setPaging(initial_paging.slice(10, 15));
    } else if (page > 15 && page <= 20) {
      setPaging(initial_paging.slice(15, 20));
    } else if (page > 20 && page <= 25) {
      setPaging(initial_paging.slice(20, 25));
    } else if (page > 25 && page <= 30) {
      setPaging(initial_paging.slice(25, 30));
    } else if (page > 30 && page <= 35) {
      setPaging(initial_paging.slice(30, 35));
    } else if (page > 35 && page <= 40) {
      setPaging(initial_paging.slice(35, 40));
    } else if (page > 40 && page <= 45) {
      setPaging(initial_paging.slice(40, 45));
    } else if (page > 45 && page <= 50) {
      setPaging(initial_paging.slice(45, 50));
    }
  }, [page]);

 

5. 첫 페이지 또는 마지막 페이지일 때 <, > disabled 하는 방법

: 비활성화 하고 싶은 li 태그의 className에 disabled만 추가하면 되는 데

첫 페이지일 때는 < disabled 하고, 마지막 페이지일 때는 > disabled 한다. (CSS에서 사용)

더보기
<li
  class={`page-item ${page === 1} ? "disabled" : undefined`}
  onClick={() => {
    if (page <= 1) {
      console.log("첫 페이지");
    } else {
      setPage(page - 1);
    }
  }}
>
  <p className="page-link">{`<`}</p>
</li>
<li
    class={`page-item ${page === end} ? "disabled" : undefined`}
    onClick={() => {
    if (page >= end) {
      console.log("마지막 페이지");
    } else {
      setPage(page + 1);
    }
    }}
    >
    <p className="page-link">{`>`}</p>
</li>

 

CSS는.. 나중에😜


전체 코드

더보기
import { useState, useEffect } from "react";
import styled from "styled-components";

const Paging2 = (props) => {
  const [page, setPage] = useState(1);
  const [end, setEnd] = useState(20);
  const initial_paging = Array.from({ length: end }, (x, i) => i + 1);
  const [paging, setPaging] = useState(initial_paging);

  useEffect(() => {
    if (page > 0 && page <= 5) {
      setPaging(initial_paging.slice(0, 5));
    } else if (page > 5 && page <= 10) {
      setPaging(initial_paging.slice(5, 10));
    } else if (page > 10 && page <= 15) {
      setPaging(initial_paging.slice(10, 15));
    } else if (page > 15 && page <= 20) {
      setPaging(initial_paging.slice(15, 20));
    } else if (page > 20 && page <= 25) {
      setPaging(initial_paging.slice(20, 25));
    } else if (page > 25 && page <= 30) {
      setPaging(initial_paging.slice(25, 30));
    } else if (page > 30 && page <= 35) {
      setPaging(initial_paging.slice(30, 35));
    } else if (page > 35 && page <= 40) {
      setPaging(initial_paging.slice(35, 40));
    } else if (page > 40 && page <= 45) {
      setPaging(initial_paging.slice(40, 45));
    } else if (page > 45 && page <= 50) {
      setPaging(initial_paging.slice(45, 50));
    }
  }, [page]);

  return (
    <CSS>
      현재 페이지 : {page}
      <br />
      <ul className="pagination">
        <li
          className={`page-item ${page === 1} ? "disabled" : undefined`}
          onClick={() => {
            if (page <= 1) {
              console.log("첫 페이지");
            } else {
              setPage(page - 1);
            }
          }}
        >
          <p className="page-link">{`<`}</p>
        </li>
        {paging.map((item, i) => {
          return (
            <li
              key={item}
              className={`page-item ${page === item ? "active" : undefined}`}
              onClick={() => {
                setPage(item);
              }}
            >
              <p className="page-link">{item}</p>
            </li>
          );
        })}
        <li
          className={`page-item ${page === end} ? "disabled" : undefined`}
          onClick={() => {
            if (page >= end) {
              console.log("마지막 페이지");
            } else {
              setPage(page + 1);
            }
          }}
        >
          <p className="page-link">{`>`}</p>
        </li>
      </ul>
    </CSS>
  );
};

const CSS = styled.div`
  margin-top: 20px;
  margin-left: 20px;
`;

export default Paging2;

댓글