앞에 만들었던 투두리스트는 기본적인 기능을 다루기 위한 간단한 프로젝트이다. 지금까지 배웠던 것들을 바탕으로 완전 실용적인 페이지는 아니지만 실제를 흉내낸 페이지를 구현해보겠다. 우리가 가장 쉽고 많이 접하는 쇼핑몰을 만들어보겠다.
먼저 어떻게 페이지를 구현할 것인지 고민해보겠다. 원래는 기본적인 로그인부터 결제창까지 다 만들어야 의미있지만 쇼핑몰에서 가장 필수적인 상품 페이지와 장바구니만 우선 구현하겠다.
- 상품을 나열하는 상품 페이지
- 구매할 상품을 담아두는 장바구니 페이지
그리고 페이지는 라우터기능을 이용해 SPA로 구현하겠다.
이제 구현할 기능을 구상해보면
- 장바구니에 추가, 삭제 기능(최대 갯수 제한)
- 한 페이지에 원하는 만큼의 상품을 보여주는 페이지네이션(정렬기능포함)
- 결제 금액을 나타내는 기능
큼지막한 기능은 이정도로 구분하고 상세한 기능은 그때그때 추가하도록 하겠다.
먼저 상품 정보는 무작위 아이템의 상품명, 가격, 이미지url주소 등으로 가상의 DB에서 정보를 받는다는 가정을 세우겠다. 아직 백엔드까지 건들지 못한 나이기 때문이다... 그래서 이 RAW정보는 건들지 않고 자바스크립트 파일에 저장해서 import해 사용하도록 하겠다.
const productItems = [ { item_no: 122997, item_name: "스탠리 클래식 런치박스", detail_image_url: "이미지url", price: 75000, score: 200, }, ...
페이지는 위에서 생각한대로 기능이 있는 페이지는 두개의 페이지만 만들겠다. 그리고 잘못된 경로로 접근했을때 띄우는 404NotFound까지 추가해주겠다.

Cart.js는 장바구니 페이지이고 Product.js는 상품 페이지이다.
이제 컴포넌트를 하나씩 만들어 페이지를 구성해보겠다!
상품 리스트를 만드는 방법은 이전에 투두리스트를 만든것과 같이 배열을 렌더링 할 것이다. 투두리스트를 할때는 리스트를 보여줄 board까지 컴포넌트화해서 페이지에 렌더링했는데 이번에는 바로 페이지에 렌더링하였다. 굳이 하나의 컴포넌트를 만들 필요가 없다고 생각했기 때문이다.
return(
<div>
{productItems && (
<div className="Board">
{productItems.map((item)=> (
<Merchandise
item={item}
key={item.item_no}
/>
))}
</div>
)}
</div>
);
우선 바로 배열을 렌더링 하는 것이 아니라 &&연산자를 통해 배열이 존재하면 렌더링을 하는 것으로 코드를 작성했다. 만약에 배열이 없을때를 대비할 수 있기 때문이다. productItems라는 상품 목록이 존재하면 전에 사용한 방법대로 map함수를 사용해 배열을 렌더링한다. 이번엔 key값을 상품 번호로 지정했다. 투두리스트에서는 index값이나 임의의 번호를 부여해 렌더링했지만 이번엔 항목마다 배열을 인식할 수 있는 고정적인 숫자가 있기 때문에 item_no으로 지정했다.
그럼 간단하게 상품 항목 한개의 컴포넌트를 만들어 보겠다.
return(
<div className="singleItem">
<img className="image" src={item.detail_image_url}></img>
<div className="info">
<h3>{item.item_name}</h3>
<h3>{item.price}원</h3><button>장바구니</button>
</div>
</div>
);
props로 넘겨준 item의 데이터를 렌더링 하는 것으로 간단하게 만들었다. 그리고 장바구니에 담을 수 있는 버튼을 추가했다.

약간의 css를 추가해서 허접하지만 간단한 상품 리스트를 만들었다.
완전 기초적인 것만 완성했다. 추가적인 기능을 하나씩 추가해가며 프로젝트를 완성해보겠다. 다음에는 장바구니 기능을 만들면서 같은 아이템이 담기지 않도록 중복검사, 3개이상의 아이템이 담기지 않도록 하는 기능 등을 구현해보겠다.