짬짬이기록하기

pagination 구현 본문

Web Development/React

pagination 구현

짬짬이기록하기 2024. 2. 7. 17:30
반응형

front 

import { useEffect, useState } from "react";
import axios from "axios";
import { Link } from "react-router-dom";

const ProductListPage = () => {
    const perPageItemNum = 3 // 한 페이지에 보여줄 항목 개수
    const perGroupPageNum = 5 // 한 그룹에 보여줄 페이지 개수

    //상태..
    const [pageState, setPageState] = useState({
        totalCount: 0, //전체 항목 개수
        totalPageCount: 0, //전체 페이지 개수 
        totalGroupCount: 0, //전체 그룹 개수
        currentPage: 1, //현재 페이지
        currentPageGroup: 0, //현재 페이지그룹
        pageArray: [], // 현재 그룹의 페이지 배열
        serverData: [] // 항목 배열
    })

    //서버연동..
    const getServerProductList = async(group, pageNum) => {
        const resp = await axios.get("http://localhost:8000/products/listpage1/" + pageNum + "/" + perPageItemNum)
        if (resp.data.status === 500) console.log("상품리스트 조회 실패")
        else {
            const totalCount = resp.data.totalCount
            const totalPageCount = Math.ceil(totalCount / perPageItemNum)
            const totalGroupCount = Math.ceil(totalPageCount / perGroupPageNum)
            const serverData = resp.data.data
            let pageArray = []

            if(totalPageCount - (group * perGroupPageNum) < perGroupPageNum) {
                pageArray = Array.from({ length: totalPageCount - (group * perGroupPageNum) }, (_, index) => index+1 + (group * perGroupPageNum))
            }else {
                pageArray = Array.from({ length: perGroupPageNum }, (_, index) => index+1 + (group * perGroupPageNum))
            }

            console.log('셋팅값', totalCount, totalPageCount, totalGroupCount, serverData, pageArray)
            setPageState({...pageState, totalCount, totalPageCount, totalGroupCount, serverData, pageArray, currentPage: pageNum, currentPageGroup:group })            
        }
    }

    useEffect(() => {
        //초기 서버 데이터 획득 호출.. 
        getServerProductList(0, 1) // 0 그룹, 1 페이지 넘버 
    }, [])

    const onClickPage = (page) => {
        getServerProductList(pageState.currentPageGroup, page)
    }
    const onMoveGroup = (group, page) => {        
        getServerProductList(group, page)
    }

    return (
    <div className="container" style={{ marginTop: "100px" }}>
        <h3>paging sample</h3>

        <table className="table">
            <thead className="table-light">
                <tr>
                    <th scope="col"><strong>product_id</strong></th>
                    <th scope="col"><strong>도서명</strong></th>
                    <th scope="col"><strong>등록이메일</strong></th>
                    <th scope="col"><strong>즉시구매가</strong></th>
                    <th scope="col"><strong>요청사항</strong></th>
                </tr>
            </thead>
            <tbody>
            {pageState.serverData.map((item, index) => (
                <tr key={index}>
                    <td>{item.product_id}</td>
                    <td>
                        <img src={`http://localhost:8000/upload/${item.picture}`} style={{ width: "60px" }} />{" "}
                        <Link to={`/products/detail/${item.product_id}`}>{item.title}</Link>
                    </td>
                    <td>{item.email}</td>
                    <td>{item.master_price}</td>
                    <td>{item.content}</td>
                </tr>
            ))}
            </tbody>
        </table>
        <p>현재페이지: {pageState.currentPage} / 총 페이지: {pageState.totalPageCount}</p>
        <p>현재그룹: {pageState.currentPageGroup} / 총 그룹: {pageState.totalGroupCount}</p>
        <p>페이지배열 : {pageState.pageArray}</p>
        <nav className="justify-content-center d-flex">
            <ul className="pagination">
                <li className={pageState.currentPageGroup === 0 ? "page-item disabled" : "page-item"}>
                    <a href="#" className="page-link" aria-label="Previous Group"
                    onClick={() => onMoveGroup(pageState.currentPageGroup - 1, (pageState.currentPageGroup - 1) * perGroupPageNum +1)}>
                        <i className="ti-angle-double-left"></i>
                    </a>
                </li>
                <li className={pageState.currentPage === pageState.pageArray[0] ? "page-item disabled" : "page-item"}>
                    <a href="#" className="page-link" aria-label="Previous page"
                    onClick={() => onClickPage(pageState.currentPage - 1)}>
                        <i className="ti-angle-left"></i>
                    </a>
                </li>
                {pageState.pageArray.map((item, index) => (
                <li className={pageState.pageArray[index] === pageState.currentPage ? "page-item active" : "page-item"} key={index}>
                    <a href="#N" className="page-link" onClick={(e) => onClickPage(Number(e.target.text))}>
                        {item}
                    </a>
                </li>
                ))}
                <li className={pageState.currentPage === pageState.pageArray[pageState.pageArray.length-1] ? "page-item disabled" : "page-item"}>
                    <a href="#" className="page-link" aria-label="Next page" 
                    onClick={() => onClickPage(pageState.currentPage + 1)}>
                        <i className="ti-angle-right"></i>
                    </a>
                </li>
                <li className={pageState.currentPageGroup === pageState.totalGroupCount - 1 ? "page-item disabled" : "page-item"}>
                    <a href="#" className="page-link" aria-label="Next Group"
                    onClick={() => onMoveGroup(pageState.currentPageGroup + 1, (pageState.currentPageGroup + 1) * perGroupPageNum + 1)}>
                        <i className="ti-angle-double-right"></i>
                    </a>
                </li>
            </ul>
        </nav>
    </div>
    )
}

export default ProductListPage

 

server side :  router 

router.get("/listpage1/:page/:count", async (req,res,next) => {
  const page = Number(req.params.page) // 페이지번호
  const count = Number(req.params.count) // 한페이지 당 보여줄 페이지 개수
  productDAO.listpage1(page, count, (resp) => {
    res.json(resp);
  });
})

server side : DAO

const getPool = require("../common/pool");

const sql = { 
  totalProducts: "SELECT COUNT(product_id) as TOTALCOUNT FROM product",
  listOnepage: "SELECT * FROM product LIMIT ?, ?",
};

const productDAO = {
  // 페이지네이션
  listpage1: async (page, count, callback) => {
    let conn = null
    try {
      conn = await getPool().getConnection()
      const [totalCount] = await conn.query(sql.totalProducts)
      const [result] = await conn.query(sql.listOnepage, [(page-1)*count, count])
      if(result) callback({status:200, data: result, totalCount: totalCount[0].TOTALCOUNT})
      else callback({status:500, message:'결과없음'})
    } catch(e) {
      console.log(e)
      return { status: 500, message: "상품조회실패", error: e }
    } finally {
      if (conn !== null) conn.release()
    } 
  },
};

module.exports = productDAO;
반응형

'Web Development > React' 카테고리의 다른 글

props.children  (0) 2024.02.08
styled-components  (0) 2024.02.08
React 강의 요점 정리  (1) 2024.02.08
검색 기능 구현  (0) 2024.02.07
검색창에 autoFocus 추가  (0) 2024.02.07