ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • React / pagination 구현하기
    Web dev/React 2022. 5. 6. 13:37
    728x90
    반응형

    리엑트로 퍼블리싱중 페이지네이션을 구현해보았다.

    페이지네이션을 만들기전 api를 만들고 axios로 데이터를 불러와 아이템을 만들어주었다.

    그부분은 생략하고 작성..

     

    1. pagination.jsx를 생성한다.

    2. list페이지에서 pagination에 props로 아이템갯수를 전달해준다.

     

    1. pagination.jsx

    list페이지에서 한페이지당 뿌릴 아이템수,총아이템수, 현재페이지를 prop으로 넘겨준다.

    그럼 총아이템수/페이지당 뿌릴 아템수로 페이지네이션 숫자를 생성

    import React from "react";
    import styled from "@emotion/styled";
    
    const PageList = styled.div`
      display: flex;
      justify-content: center;
      align-items: center;
      text-align: center;
      margin: 40px 0;
    `;
    
    const PageItem = styled.a`
      display: block;
      width: 25px;
      height: 25px;
      line-height: 25px;
      box-sizing:border-box;
      font-size: 14px;
      font-weight: 400;
      color: ${props => (props.isActive ? '#fff' : '#666')};
      background-color: ${props => (props.isActive ? '#666' : '#fff')};
      border-radius: 100%;
      cursor: pointer;
    `;
    
    const Pagination = ({ itemPerPage, totalItem, paginate }) => {
    
      const pageItem = document.getElementsByClassName("page-item")
    
      const pageClick = (number) => {
        for(let i = 0; i < pageItem.length; i++){
          pageItem[i].style.backgroundColor = "#fff"
          pageItem[i].style.color = "#666"
        }
        pageItem.item(number - 1).style.background = "#666";
        pageItem.item(number - 1).style.color = "#fff";
      }
    
      const pageNumbers = [];
      for (let i = 1; i <= Math.ceil(totalItem / itemPerPage); i++) {
        pageNumbers.push(i);
      }
    
      return (
        <div>
          <nav>
            <PageList>
              {pageNumbers.map((number) => (
                <PageItem 
                key={number} 
                isActive={number === 1}
                className="page-item"
                onClick={() =>{
                  paginate(number) 
                  pageClick(number)
                  }} 
                >
                {number}
                </PageItem>
              ))}
            </PageList>
          </nav>
        </div>
      );
    };
    
    export default Pagination;

     

    2. list.jsx

    currentPage는 초기값1, itemPerPages는 8개씩 뿌려줄꺼라 8이라 했다.

    pagination에 아이템을 클릭하면 currentPage값이 바뀐다.

    그럼 currentItems는 처음엔 0~8,9~16,16~24 이런식으로 누른 숫자에 따라 8개씩 반환하여 뿌려준다.

    import axios from 'axios';
    import React, { useEffect, useState } from 'react'
    import { Link} from 'react-router-dom'
    import sub from '../../assets/css/sub/sub.module.css'
    import Pagination from './pagination';
    import { priceComma } from '../Hook/PriceComma';
    
    
    export default function AllItem() {
      const [item, setItem] = useState([]);
      const [currentPage, setCurrentPage] = useState(1);
      const [itemsPerPage] = useState(8);
    
      useEffect(() => {
        const callApi = async () => {
        await axios.get("/api")
          .then((res) => {
            setItem(res.data.product)
        });
        };
        callApi();
      }, []);
    
      const indexOfLast = currentPage * itemsPerPage;
      const indexOfFirst = indexOfLast - itemsPerPage;
      function currentItems(item) {
        let currentItems = 0;
        currentItems = item.slice(indexOfFirst, indexOfLast);
        return currentItems;
      }
    
      return (
        <>
        {currentItems(item).map((item) => (
            <Link to={`/ItemDetail/${item.id}`} key={item.id} className={sub.item}>
            <div className={sub.thumb}>
              <img src={item.imageURL} alt="" />
            </div>
            <div className={sub.text}>
                <p className={sub.desc}>{item.desc}</p>
                <p className={sub.name}>{item.name}</p>
                <div className={sub.price}>
                    <span className={sub.normal_price}>{priceComma(item.price)}원</span>
                    <span className={sub.sale_price}>{priceComma(item.sale_price)}원</span>
                </div>
            </div>
          </Link>
        ))
        }
      <Pagination itemPerPage={itemsPerPage} totalItem={item.length} paginate={setCurrentPage}></Pagination>
      </>
      )
    }

    728x90
    반응형

    댓글

Designed by Tistory.