👩‍💻
Megaptera Frontend
  • 주차별 학습
    • megaptera-front
    • 1. 개발 환경
      • 1. 개발 환경
      • 2. TypeScript
      • 3. React
      • 4. Testing Library
      • 5. Parcel & ESLint
      • 한 주를 마치며
    • 2. JSX
      • 1. JSX
      • 한 주를 마치며
    • 3. React로 사고하기
      • 1. React Component
      • 2. React State
      • 한 주를 마치며
    • 4. React Hooks
      • 1. Express
      • 2. Fetch API & CORS
      • 3. React의 Hook
      • 4. useRef & Custom Hook
      • 5. usehooks-ts
      • 한 주를 마치며
    • 5. 테스트
      • 1. TDD
      • 2. React Testing Library
      • 3. MSW
      • 4. Playwright
      • 한 주를 마치며
    • 6. External Store
      • 1. External Store
      • 2. TSyringe
      • 3. Redux 따라하기
      • 4. usestore-ts
      • 한 주를 마치며
    • 7. React Router
      • 1. Routing
      • 2. Routes
      • 3. Router
      • 4. Navigation
      • 한 주를 마치며
    • 8. CSS in JS
      • 1. Design System
      • 2. Style Basics
      • 3. CSS in JS
      • 4. styled-components
      • 5. props와 attrs
      • 6. Global Style & Theme
      • 한 주를 마치며
    • 9. 쇼핑몰 목록, 상품 페이지
      • 1. 개발하기 전 준비
      • 2. 목록 보기
      • 3. 상품 상세 보기
      • 4. 장바구니 보기
      • 5. 장바구니에 상품 담기
      • 한 주를 마치며
    • 10. 사용자 인증, 인가
      • 1. 로그인
      • 2. 로그아웃
      • 3. 회원가입
      • 4. 주문 목록 & 주문 상세
      • 한 주를 마치며
    • 11. 주문, 결제
      • 1. 배송 정보 입력
      • 2. 포트원 결제 요청
      • 3. 배송 및 결제 정보 전달
      • 한 주를 마치며
    • 12. 어드민
      • 1. 관리자 웹 사이트 개발 시작
      • 2. 로그인, 사용자 목록
      • 3. 카테고리 관리
      • 4. 주문 관리
      • 5. 상품 관리
      • 한 주를 마치며
Powered by GitBook
On this page
  • 1. 장바구니 데이터 받아오기
  • CartPage.tsx 작성
  • useFetchCart hook 생성
  • CartStore hook 생성
  • 2. 장바구니 보기 페이지 UI 구현하기
  • CartView.tsx 컴포넌트 구현
  • LineItemView 컴포넌트 생성
  • Options 컴포넌트 생성
  • cURL을 이용해서 임의로 장바구니에 상품 담기
  • 3. 테스트 작성하기
  • backdoor
  1. 주차별 학습
  2. 9. 쇼핑몰 목록, 상품 페이지

4. 장바구니 보기

Previous3. 상품 상세 보기Next5. 장바구니에 상품 담기

Last updated 2 years ago

1. 장바구니 데이터 받아오기

🎯 장바구니에 상품 담기 기능을 만들기 전에, 비교적 쉬운 장바구니 보기 작업을 먼저 해보기

CartPage.tsx 작성

const {cart} = useFetchCart();

useFetchCart hook 생성

  • src/hooks

  • 원래는 API을 호출할 때 엑세스 토큰을 넘겨주어, '내 카트'를 호출해야 함

  • 지금은 모두가 같은 카트를 이용하도록 구현됨

  • 이후 회원가입, 로그인 구현 시 처리할 예정

export default function useFetchCart() {
  const store = container.resolve(CartStore);

  const [{ cart }] = useStore(store);

  useEffectOnce(() => {
    store.fetchCart();
  });

  return { cart };
}

CartStore hook 생성

  • src/stores

구현 내용

  1. 타입 지정

    • ProductDetail처럼 Null Object를 만들어서 쓰면 더 좋음

  2. API Service에 fetchCart 추가

    • ApiService에서 fetchCart 구현

  3. setCart @Action() 추가

async fetchCart(): Promise<Cart> {
  const { data } = await this.instance.get('/cart');
  return data;
}

2. 장바구니 보기 페이지 UI 구현하기

Cart 타입과 Cart 컴포넌트의 이름이 겹치는 이슈

  1. Cart 타입을 가져올 때 as CartType을 써서 타입의 이름을 교체

  2. Cart 컴포넌트를 CartView 등의 다른 이름으로 교체 ✅

CartView.tsx 컴포넌트 구현

  • src/components/cart/CartView.tsx

const Container = styled.div`
  table {
    width: 100%;
  }

  th, td {
    padding: .5rem;
    text-align: left;
  }
`;

type CartViewProps = {
  cart: Cart;
};

export default function CartView({ cart }: CartViewProps) {
  if (!cart.lineItems.length) {
    return (
      <p>장바구니가 비었습니다</p>
    );
  }

  return (
    <Container>
      <table>
        <thead>
          <tr>
            <th>제품</th>
            <th>단가</th>
            <th>수량</th>
            <th>금액</th>
          </tr>
        </thead>
        <tbody>
          {cart.lineItems.map((lineItem) => (
            <LineItemView
              key={lineItem.id}
              lineItem={lineItem}
            />
          ))}
        </tbody>
        <tfoot>
          <tr>
            <th colSpan={3}>
              합계
            </th>
            <td>
              {numberFormat(cart.totalPrice)}
              원
            </td>
          </tr>
        </tfoot>
      </table>
    </Container>
  );
}

LineItemView 컴포넌트 생성

이름 중복 이슈로 인해 LineItem도 LineItemView라는 이름으로 생성

      <td>
        <Link to={`/products/${lineItem.product.id}`}>
          {lineItem.product.name}
        </Link>
        <Options options={lineItem.options} />
      </td>
  • 해당 상품으로 돌아갈 수 있는 Link 추가

  • 선택한 옵션을 볼 수 있는 Options 컴포넌트 생성

Options 컴포넌트 생성

const Container = styled.div`
  margin-top: .5rem;
  font-size: 1.4rem;
`;

type OptionsProps = {
  options: OrderOption[];
}

export default function Options({ options }: OptionsProps) {
  if (!options.length) {
    return null;
  }

  const text = options
    .map((option) => `${option.name}: ${option.item.name}`)
    .join(', ');

  return (
    <Container>
      ({text})
    </Container>
  );
}

cURL을 이용해서 임의로 장바구니에 상품 담기

서버와 통신할 수 있는 커맨드 명령어 툴

curl -X POST https://shop-demo-api-01.fly.dev/cart/line-items \
  -H "Content-Type: application/json" \
  --data '
    {
      "productId": "0BV000PRO0001",
      "options": [
        {
          "id": "0BV000OPT0001",
          "itemId": "0BV000ITEM001"
        },
        {
          "id": "0BV000OPT0002",
          "itemId": "0BV000ITEM005"
        }
      ],
      "quantity": 1
    }
  '

3. 테스트 작성하기

backdoor

데이터베이스를 초기화해서 다시 테스트할 수 있도록 함 백엔드 개발자와 얘기해서 만들 것

🚨 테스트 환경에서만 사용해야 함, 실제 서비스에선 절대 나가면 안됨

🔗 실습 링크 : 장바구니 보기 페이지 UI 구현
cURL
🔗 실습 링크 : 장바구니 보기 CartStore, useFetchCart 구현