[TIL] 장바구니 구현하기 - 총 결제금액

·2024년 1월 16일
1

TIL series

목록 보기
25/28
post-thumbnail

어제 하루종일 삽질한 문제 해결


장바구니에서 총 결제 금액이 문제였다,, 카트 컴포넌트에서 상품 수량이 변경되면 거기에 맞게 바로바로 업데이트 됐으면 좋겠는데!!

문제점

처음에 생각한 로직은 페이지 처음 로드할 때 db에서 불러온 초기값을 가지고 총 결제금액을 계산한 후, 각 컴포넌트에서 수량이 변경되었을 때에 맞춰 더하고 빼주려고 했다.
react-hook-form을 이용해 만든 number input 컴포넌트에서 변경 이전 값을 가져올 방법이 없다..!!



해결방법

페이지에서 아이템마다 총 금액을 담는 배열을 만들어서 각 컴포넌트에서 업데이트하고, 페이지에서는 배열에 있는 금액의 총합을 이용하도록 했다.

"use client";
import React, { useEffect, useState } from "react";
import Section from "@/components/layout/Section";
import CartItem from "./CartItem";
import { useCart } from "@/hooks";
import Link from "next/link";
import PageBreadCrumb from "@/components/layout/PageBreadCrumb";
	...
const Page = () => {
	...

  const { cart, isLoading } = useCart({ userId: auth, cartId: "" });

  const [cartPrice, setCartPrice] = useState<number[]>([]);
	//카트 아이템당 총 금액을 담는 배열
  return (
    <>
      <PageBreadCrumb linkList={linkList} />
      <Section title={"장바구니"} isCenter={true}>
        {logedIn ? (
         			...
         
                  {(cart as CartBox[]).map((cartItem, idx) => {
                    return (
                      cartItem && (
                        <CartItem
                          cart={cartItem}
                          cartPrice={cartPrice}
                          setCartPrice={setCartPrice}
                          idx={idx}
                          key={cartItem.id}
                        />
                      )
                    );
                  })}
                
                  ...
                  
                    <div className="text-right text-[16px] font-bold mr-1">
                      총 결제금액
                      <p className="text-[24px] font-bold inline-block ml-1">
                        {" "}
                        {cartPrice.reduce((acc, num) => acc + num, 0)}//총 결제금액은 배열의 총합으로 구하기
                        ...
import React, { useEffect, useState } from "react";
import Image from "next/image";
import { CartBox } from "./page";
import { VscChromeClose } from "react-icons/vsc";
import { useCart } from "@/hooks";
import { useForm } from "react-hook-form";
import NumberInput from "@/components/NumberInput";

...

const CartItem = (cart: Props) => {
  const { count, id, product_id, store_id, user_id, rent_date, store, product } = cart.cart;
  const { name, thumbnail, price, percentage_off, category } = product;
  const { cartPrice, setCartPrice, idx } = cart;

  const [isVisible, setIsVisible] = useState(true);

  const { updateCountMutation, deleteCart } = useCart({ userId: user_id, cartId: id });

  const {
    register,
    setValue,
    getValues,
    watch,
    formState: { errors }
  } = useForm({ mode: "onChange" });
  const watchCount = watch();

  useEffect(() => {
    const updateCount = async () => {
      if (isVisible) {
        //cartPrice 배열에 총액
        cartPrice[idx] = getValues("count") * price;
        setCartPrice([...cartPrice, 0]);
        updateCountMutation.mutate(watchCount.count);
      } else {
        //삭제했을 때
        cartPrice[idx] = 0;
        setCartPrice([...cartPrice, 0]);
      }
    };
    updateCount();
  }, [watchCount.count, isVisible]);

  const handleCartDelete = () => {
    setIsVisible(false);
    deleteCart(id);
  };

  return (
    <>
     ...
    </>
  );
};

export default CartItem;

짜잔
수량이 바뀌어도, 삭제해도 잘 작동한다.

0개의 댓글