MINE - 메인 페이지 2. AuctionList

Byeonghyeon·2024년 5월 9일
0

MINE

목록 보기
4/10

AuctionList

AuctionList는 간단하다. 상품 목록을 서버에서 전달받아 표시만 해주면 된다.

작동 순서는 다음과 같다.

  1. 서버에게 post로 상품 목록을 요청한다.
  2. 서버에게 상품 목록을 전달받아 '최신순'으로 정렬한다.(기본이 되는 정렬 방식이 최신순이기 때문이다.)
  3. 정렬한 상품목록을 표시한다.

AuctionList의 부가 기능은 상품 정렬과 페이지네이션이다.

상품 정렬

상품 정렬의 경우 역시 select 태그를 이용해 정렬하고 싶은 옵션을 선택한다.

현재 MINE에는 '최신순', '마감임박순', '낮은가격순', '높은가격순' 4개의 정렬 옵션이 존재한다.

sort 함수를 이용해 각 옵션별로 정렬하였다.

  1. 최신순
 const sortedByRecent = [...products].sort((a, b) => new Date(b.auctiontime).getTime() - new Date(a.auctiontime).getTime());

상품이 생성된 시간(여기서는 auctiontime이라는 변수명을 사용하였다.)을 비교해 정렬한다.

  1. 마감임박순
const sortedByDeadline = [...products].sort((a, b) => new Date(a.auctiondeadline).getTime() - new Date(b.auctiondeadline).getTime());

판매자가 설정한 마감 시간(여기서는 auctiondeadline이라는 변수명을 사용하였다.)을 비교해 정렬한다.

  1. 낮은가격순과 높은가격순
/* 낮은가격순 */
const sortedByLowerPrice = [...products].sort((a, b) => Number(a.auctionbidprice) - Number(b.auctionbidprice));

/* 높은가격순 */
const sortedByHigherPrice = [...products].sort((a, b) => Number(b.auctionbidprice) - Number(a.auctionbidprice));

현재 상품의 가격(여기서는 auctionbidprice라는 변수명을 사용하였다.)을 비교해 정렬한다.

setProducts(sortedByHigherPrice);

이렇게 정렬된 상품을 useState를 이용해 저장한 후

{Products.map((product) => (
              <Link href={`/product/${product.auctionid}`} key={product.auctionid} passHref>
                <ProductBlock product={product} />
              </Link>
))}

map 함수를 이용해 표시해주면 된다.

페이지네이션

페이지네이션 같은 경우 이미 전에 한 번 다뤄본 적이 있기 때문에 크게 어렵지 않았다.

const PAGE_SIZE = 8; // 한 페이지에 표시할 상품의 수

const [currentPage, setCurrentPage] = useState<number>(1);

먼저 한 페이지에 표시할 상품의 수를 지정해주고(나는 8개로 지정했다.), 현재 페이지 상태를 생성해준다.

const totalPages = Math.ceil(products.length / PAGE_SIZE);

상품 목록이 저장되는 배열인 products의 길이를 PAGE_SIZE로 나눠 총 페이지 수를 계산한다.

const startIndex = (currentPage - 1) * PAGE_SIZE;
const endIndex = startIndex + PAGE_SIZE;
const currentProducts = products.slice(startIndex, endIndex);

그 후 현재 페이지에 해당하는 상품 목록을 결정한다.

  • startIndex는 현재 페이지에서 보여져야 할 상품의 시작 인덱스를 계산한다. 현재 페이지가 1이면 시작 인덱스는 0이다. 현재 페이지가 2이면 시작 인덱스는 PAGE_SIZE만큼 증가한 값이 된다. 따라서 (currentPage - 1) * PAGE_SIZE로 계산된다.
  • endIndex는 시작 인덱스에 페이지 사이즈를 더해 현재 페이지에서 보여져야 할 상품의 마지막 인덱스를 계산한다. 시작 인덱스부터 페이지 사이즈만큼의 상품을 보여준다.
  • currentProducts는 slice 함수를 사용하여 전체 상품 목록(products)에서 현재 페이지에 해당하는 상품 목록을 가져온다. 시작 인덱스부터 마지막 인덱스 이전까지의 상품들을 반환한다.
{currentProducts.map((product) => (
              <Link href={`/product/${product.auctionid}`} key={product.auctionid} passHref>
                <ProductBlock product={product} />
              </Link>
))}

이렇게 계산된 currentProduts를 map 함수를 이용해 나열한다.

{Array.from({ length: totalPages }, (_, index) => (
              <button
                key={index}
                onClick={() => handlePageChange(index + 1)}
                className={`mx-1 py-1 px-3 border rounded ${currentPage === index + 1 ? "bg-gray-300" : ""}`}
              >
                {index + 1}
              </button>
            ))}

이제 페이지 버튼을 생성한다.

페이지 수만큼의 배열을 생성하고 인덱스마다 페이지 버튼을 생성한다. 버튼을 클릭하면 handlePageChange 함수가 호출되고 해당 페이지 번호(index + 1)가 인수로 전달된다.

const handlePageChange = (page: number) => {
    setCurrentPage(page);
  };

handlePageChange에서는 전달받은 인수를 현재 페이지로 지정하고 현재 페이지에 해당하는 상품들을 나열하게 된다.

0개의 댓글