[리액트 X 타입스크립트] Fake Store Api를 이용하여 쇼핑몰 장바구니 기능 만들기

hoonie·2021년 8월 1일
1
post-thumbnail

안녕하세요. 이번에는 Fake Store Api를 활용하여 쇼핑몰 아이템 리스트를 불러오고 그것을 이용하여 장바구니에 넣고 삭제하는 기능을 타입스크립트와 리액트를 이용해서 만들어보았습니다.

깃허브 url - https://github.com/zlzlzlmo/shopping_cart-with-react-ts

UI는 material ui를 활용하였습니다.

  1. fetch api를 이용하여 data를 json 형태로 받아와줍니다.

const getProducts = async (): Promise<CartItemType[]> => {
  return await (await fetch("https://fakestoreapi.com/products")).json();
};
  1. react-query의 useQuery 리액트 훅을 사용하여 data를 받아와준후 map함수를 이용하여 item 리스트를 뿌려줍니다.
  const { data, isLoading, error } = useQuery("products", getProducts);
  1. data의 아이템별 타입에 맞는 타입을 설정해줍니다.

export type CartItemType = {
  id: number;
  category: string;
  description: string;
  image: string;
  price: number;
  title: string;
  amount: number;
};

  1. 장바구니에 담긴 상태값을 관리하기 위한 useState를 만들어줍니다.
const [cartItems, setCartItems] = useState<CartItemType[]>([]);
  1. 장바구니 추가 버튼을 클릭했을시 해당 상품이 장바구니에 들어가기 위한 함수를 만들어줍니다.

  const handleAddToCart = (clickedItem: CartItemType) => {
    setCartItems((prev) => {
      const isItemInCart = prev.find((item) => item.id === clickedItem.id);
      if (isItemInCart) {
        return prev.map((item) =>
          item.id === clickedItem.id
            ? { ...item, amount: item.amount + 1 }
            : item
        );
      }
      return [...prev, { ...clickedItem, amount: 1 }];
    });
  };

코드 설명

  • 클릭한 아이템이 기존에 장바구니에 등록되어있는지 아닌지에 대한 유무를 find함수를 이용하여 찾아냄 -> 만약 있다면 기존에 장바구니에 등록되어있던 아이템 배열을 돌려서 클릭한 아이템과 같은 아이템이 발견될시 해당 장바구니 상품 수량을 +1 시킴 -> 만약 없다면 새로 장바구니 리스트에 추가시키고 amount 키값을 추가하여 수량을 1로 만듬
  1. 등록된 장바구니 상품 수량을 표시함

  const getTotalItems = (items: CartItemType[]) => {
    return items.reduce((ack: number, item) => {
      return ack + item.amount;
    }, 0);
  };

코드 설명

  • 장바구니에 등록되어있는 item 리스트를 매개변수로 넣어서 리듀스 초기값을 0으로 설정하고 reduce를 돌림 -> 장바구니 추가할때 추가했던 amount 키값을 계속 더하여 총 amount를 return함
  1. 장바구니에 등록된 제품 수량을 차감시키기
const handleRemoveFromCart = (id: number) => {
    setCartItems((prev) =>
      prev.reduce((ack, item) => {
        if (item.id === id) {
          if (item.amount === 1) return ack;
          return [...ack, { ...item, amount: item.amount - 1 }];
        } else {
          return [...ack, item];
        }
      }, [] as CartItemType[])
    );
  };

코드 설명

  • reduce의 초기값을 CartItemType[] 타입을 받는 배열로 설정-> 만약 마이너스 버튼을 클릭한 아이템의 수량이 1개라면 reduce 이전 배열을 리턴하여 리스트에서 삭제 -> 2개 이상이라면 수량 1개를 감소시킴

  1. cartItem 리스트가 없다면 "등록된 상품이 없습니다." 문구 출력
  {cartItems.length === 0 ? <p>현재 등록된 상품이 없습니다.</p> : null}

타입스크립트와 리액트의 조합을 이용하여 간단한 어플리케이션을 만들어보았습니다. 아직 많이 낯설고 미숙하지만, 지속적으로 연습하다보면 숙달될것이라고 믿고있습니다. 앞으로 지속적인 연습을 통하여 리액트와 타입스크립트 꿀조합을 능숙하게 사용하는 날이 오면 좋겠습니다.

감사합니다

0개의 댓글