React. 장바구니

김병화·2022년 12월 14일
0
post-thumbnail

이 전에 수량 변경 컴포넌트인 <QuantityCounter />에서 수량이 변경됨에 따라 product data 자체의 quantity가 변경되도록 해주었다.

그러나 장바구니 페이지를 만들면서 그렇게 하면 안된다는 것을 알았다.
<QuantityCounter />를 product 자체의 data와 바인딩을 시키게 되면, 장바구니 페이지에서 처음 렌더링 될 때 carts(장바구니 배열)의 정보가 아닌 product의 quantity가 나타나게 된다.

따라서 Component들의 props를 다시 설정해주었다.

1. 최상위 부모 컴포넌트인 <App />에 장바구니 data를 담을 배열 carts를 선언해준다.

여기서 장바구니 정보 배열 carts가 필요한 곳에 props로 내려준다.

function App() {
  const [carts, setCarts] = useState([]);

  return (
    <>
      <Reset />
      <GlobalStyle />
      <BrowserRouter>
      <ScrollToTop />
        <Header carts={carts} />
        <Routes>
          <Route path='/' element={<Home />} />
          <Route path='/BeautyHome' element={<BeautyHome />} />
          <Route path='/SignUp' element={<SignUp />} />
          <Route path='/SignIn' element={<SignIn />} />
          <Route path='/Cart' element={<Cart carts={carts} setCarts={setCarts} />} />
          <Route path='/Product/:id' element={<Product carts={carts} setCarts={setCarts}/>} />
        </Routes>
          <Footer />
      </BrowserRouter>
    </>
  );
}


2. 장바구니 추가 버튼이 있는 상품 상세 페이지 <Product />에서는 count 변수를 통해 <QuantityCounter />를 제어한다.

countcarts에 들어갈 cartItem에 이용된다. → cart.count 만큼 carts에 들어감.

function Product({ carts, setCarts }) {
    const {id} = useParams();
    
    const[products, setProducts] = useState([]);
    useEffect( () => {
        fetch('http://localhost:3000/data/product.json',{     
        method: 'GET'})
        .then(res => res.json()) 
        .then(data => {
            setProducts(data); 
        });
    },[])

   let product = []; 
   for(let i=0; i<products.length; i++){  
    if(products[i].id === Number(id)){  
        product = products[i];
        break;
    }
   }

    const[count, setCount] = useState(1);

    const getCount = (count) => {
        setCount(count);             
    }

    const setQuantity = (id, quantity) => {
        const found = carts.filter((el) => el.id === id)[0];
        const idx = carts.indexOf(found);
        const cartItem = {
            id: product.id,
            name: product.name,
            description: product.description,
            img: product.img,
            price: product.price,
            quantity: quantity,
            delivery: product.delivery,
            keep: product.keep,
            checked: true
        };

        setCarts([ ...carts.slice(0, idx), cartItem, ...carts.slice(idx+1) ]);
        Swal.fire({
            text: '장바구니에 추가되었습니다.',
            confirmButtonText: '확인',
            confirmButtonColor: 'rgb(95, 0, 128)'
        });
    }

    const addToCart = () => {
        const cartItem = {
            id: product.id,
            name: product.name,
            description: product.description,
            img: product.img,
            price: product.price,
            quantity: count,
            delivery: product.delivery,
            keep: product.keep,
            checked: true
        };

        const found = carts.find((el) => el.id === cartItem.id);    

        if(found) {
            setQuantity( cartItem.id, found.quantity + count );
         
        } else {
            setCarts([...carts, cartItem]);
            Swal.fire({
                text: '장바구니에 추가되었습니다.',
                confirmButtonText: '확인',
                confirmButtonColor: 'rgb(95, 0, 128)'
            });
        }
    }

    const PlusQuantity = () => {
        getCount(count => count + 1);
    }

    const MinusQuantity = () => {
        if (count>=2) {
            getCount(count => count - 1);
        }
        else return;
    }
   	return (
      blah~
      
      <div className={styles.QuantityCounter}>
          <button class={styles.minusButton} onClick={MinusQuantity}>-</button>
          <button class={styles.quantityButton}>{count}</button>
          <button class={styles.plusButton} onClick={PlusQuantity}>+</button>    
      </div>

		blah~
      );
  }


3. 장바구니 상품 컴포넌트 <CartProudct /> 에선 carts 배열에 들어있는 cartItem 만큼의 quantity를 렌더링 해야하기 때문에 carts.map으로 가져온 cart의 quantity를 이용한다.

function CartProduct({ carts, cart, setCarts, getNowQuantity }) {
    const[ counterQuantity, setCounterQuantity ] = useState(1); 

    const PlusQuantity = () => {
        setCounterQuantity(counterQuantity => counterQuantity + 1);
        cart.quantity += 1;
        getNowQuantity(cart.quantity);
    }

    const MinusQuantity = () => {
        if (cart.quantity>=2) {
            setCounterQuantity(counterQuantity => counterQuantity - 1);
            cart.quantity -= 1;
            getNowQuantity(cart.quantity);
        }
        else return;
    }

    const removeFromCart = (id) => {
        setCarts(carts.filter( (el) => el.id !== cart.id ));
    }
    
    return (
		blah~
      
    	<div className={styles.QuantityCounter}>
 			<button class={styles.minusButton} onClick={MinusQuantity}>-</button>
    		<button class={styles.quantityButton}>{cart.quantity}</button>
    		<button class={styles.plusButton} onClick={PlusQuantity}>+</button>     
        </div>

		blha~
	);
}

0개의 댓글