2차 프로젝트 2주차 4일차

이청원·2023년 10월 6일
0
import React, { useEffect, useState } from 'react';
import { useSearchParams } from 'react-router-dom';
import Goods from '../../components/Goods/Goods';
import './Product.scss';
import Pagination from '../../components/Pagination/Pagination';

const size = 6;
const pageLimit = 5;

const Product = () => {
  const [data, setData] = useState({});
  const [sort, setSort] = useState(sortingList[0].value);

  //페이지네이션
  const [currentPage, setCurrentPage] = useState(1); //현재페이지
  const [totalPage, setTotalPage] = useState(0);
  const [searchParams, setSearchParams] = useSearchParams();
  const category = searchParams.get('category');

  const changeSort = (e) => {
    setSort(e.target.value);
  };

  useEffect(() => {
    setCurrentPage(1);
  }, [category]);
  useEffect(() => {
    window.scrollTo({ top: 0, behavior: 'smooth' });
  }, [sort, currentPage]);
  useEffect(() => {
    fetch(
      `http://10.58.52.209:8000/products?category=${category}&sort=${sort}&page=${currentPage}&size=${size}`,
    )
      .then((res) => {
        return res.json();
      })
      .then((result) => {
        const totalPage = Math.ceil(result.data.total / size);
        setTotalPage(totalPage);
        setData(result.data);
      });
  }, [searchParams, sort, currentPage, category]);
  if (!Object.keys(data).length > 0) return null;

  return (
    <div className="product">
      <div className="goodsContainer">
        <h1>{data.category}</h1>
        <div className="total">
          <p>{`${data.total}`}</p>

          <select className="select" onChange={changeSort}>
            {sortingList.map((list) => {
              return (
                <option key={list.id} value={list.value}>
                  {list.name}
                </option>
              );
            })}
          </select>
        </div>
        <Goods datalist={data.list} />
      </div>
      <Pagination
        pageLimit={pageLimit}
        currentPage={currentPage}
        setCurrentPage={setCurrentPage}
        totalPage={totalPage}
      />
    </div>
  );
};

export default Product;

const sortingList = [
  {
    id: 0,
    name: '신상품순',
    value: 'latest',
  },
  {
    id: 1,
    name: '낮은가격순',
    value: 'lowprice',
  },
  {
    id: 2,
    name: '높은가격순',
    value: 'highprice',
  },
];
import React, { useEffect, useState } from 'react';
import './Pagination.scss';

const Pagination = (props) => {
  const { pageLimit, currentPage, setCurrentPage, totalPage } = props;

  const [pageArray, setPageArray] = useState([]);

  useEffect(() => {
    const arr = [];
    const startPage = Math.floor((currentPage - 1) / pageLimit) * pageLimit + 1;
    const endPage = Math.min(startPage + pageLimit - 1, totalPage);

    for (let i = startPage; i < endPage + 1; i++) {
      arr.push(i);
    }
    setPageArray(arr);
  }, [totalPage, currentPage, pageLimit]);

  return (
    <div className="pagination">
      <div className="paginationBox">
        {currentPage === 1 ? null : (
          <span
            className="arrow"
            onClick={() => setCurrentPage(currentPage - 1)}
          >
            {'<'}
          </span>
        )}

        {pageArray.map((num) => {
          return (
            <span
              key={num}
              onClick={() => setCurrentPage(num)}
              className={num === currentPage ? 'clicked' : 'notClicked'}
            >
              {num}
            </span>
          );
        })}
        {currentPage === totalPage ? null : (
          <span
            className="arrow"
            onClick={() => setCurrentPage(currentPage + 1)}
          >
            {'>'}
          </span>
        )}
      </div>
    </div>
  );
};

export default Pagination;

페이지네이션!!

     .then((result) => {
       const totalPage = Math.ceil(result.data.total / size);
       setTotalPage(totalPage);
	const [totalPage, setTotalPage] = useState(0);

Math.ceil 함수는 반올림 함수이다. 백엔드에서 받아온 제품의 총 데이터개수를 받아
size 한페이지에 보여줄 제품 개수를 나누기하여서 내가 필요한 총 데이터페이지 개수를
useState 훅을 이용하여 totalPage 저장한다.

const size = 6;
const pageLimit = 5;
const [currentPage, setCurrentPage] = useState(1);

size 내가 보여줄 게시물 수를 6개로 전역변수에 지정하고 만약게시물이 총개수가 36개라면
페이지에서 보여줄 페이지 숫자는 1 2 3 4 5 일것이다. 그 리미트를 5페이지 지정하고 나머지 6개의 대한 페이지는 6 이 된다는 pageLimit 을 전역변수에 지정하고! currentPage 기본값을 (1)을 지정하여 currentPage 에 저장한다!!

  useEffect(() => {
    const arr = [];
    const startPage = Math.floor((currentPage - 1) / pageLimit) * pageLimit + 1;
    const endPage = Math.min(startPage + pageLimit - 1, totalPage);

    for (let i = startPage; i < endPage + 1; i++) {
      arr.push(i);
    }
    setPageArray(arr);
  }, [totalPage, currentPage, pageLimit]);

start페이지 end페이지를 구한다. Math.floor() 올림함수이다.
currentPage(스테이트에 저장된 현재페이지)-1 /나누기 pageLimit(페이지에 그려내는 페이지개수 수) 한후 * 곱하기 pageLimit 한후 + 1 을하면 내가지금 있는 위치 시작페이지를 구할수있다.

맨위 코드를 보면 pageLimit=5 로 지정하였고 내가 지금있는 페이지가 1 이라고 했을때

1 - 1 = 0 >다음> 0 / 5 = 0 >다음> 0 * 5 + 1 = 1 이다
내가 있는 시작페이지 1페이지라는것을 알수있다.

endpage 구하는방법은 일단 Math.min() 함수란? (숫자,숫자) 위 두가지 수가 있다고 가정했을때 작은 숫자를 아웃풋 해주는 함수이다.

totalPage는 내가 필요한 총페이지 개수 이다.위에서 구했지만 다시!! 총제품개수에
한페이지당 노출할 개수를 나누기 해주고 Math.ceil 함수를 통해 반올림 처리를한다.
그러면 내가 필요한 총 페이지 개수를 구할수있다.

     .then((result) => {
       const totalPage = Math.ceil(result.data.total / size);
       setTotalPage(totalPage);

Math.min함수안에 Math.min(startPage + pageLimit - 1, totalPage)

startPage 1 이라고 가정했을때!! totalPage 내가필요한 토탈 페이지가 10이라고하면 ?
1 + 5 - 1 >>다음>> (5 , 10 ) 5를 아웃풋한다. 그러면 endpage 를 구할수있다.

useEffect(() => {
    const arr = [];
    const startPage = Math.floor((currentPage - 1) / pageLimit) * pageLimit + 1;
    const endPage = Math.min(startPage + pageLimit - 1, totalPage);

    for (let i = startPage; i < endPage + 1; i++) {
      arr.push(i);
    }
    setPageArray(arr);
  }, [totalPage, currentPage, pageLimit]);

내가 필요한 총페이지 , 스타트 페이지 , 엔드페이지 , 사이즈 , 페이지리밋 을구하고난후

useEffect() 함수안에 const arr = []; 빈배열을 할당한후 의존성 배열안에
토탈 페이지 현재 페이지 페이지 리밋을 기입하고 페이지가 클릭될때마다 리랜더링되면서 내가 필요한 총 페이지의 페이지 개수가 그려질것이다.

profile
어제보다 나은 사람이 되도록 노력하자!

0개의 댓글