sprint - Cmarket hooks

FeelSoo·2022년 4월 25일
0

CodeStates

목록 보기
23/43
post-thumbnail










App.js


변수 ( 함수를 담은 ) addCart, removeCart, Quantity 작성


import React, { useState } from 'react';
import Nav from './components/Nav';
import ItemListContainer from './pages/ItemListContainer';
import './App.css';
import {
  BrowserRouter as Router,
  Switch,
  Route,
} from "react-router-dom";
import ShoppingCart from './pages/ShoppingCart';
import { initialState } from './assets/state';

function App() {

  const [items, setItems] = useState(initialState.items);
  const [cartItems, setCartItems] = useState(initialState.cartItems);


  
  const addCart = (itemId) => {                                     // //물건을 추가할 때 1. 기존의 물건인지 2. 새로운 물건인지 체크 
    const exist = cartItems.filter((el) => el.itemId === itemId)[0] // 기존 아이템이 들어온 경우
    if(exist) {
      console.log('이미 존재하는 상품입니다.')
      Quantity(itemId, exist.quantity + 1)
    }
    else {                                                        // 새로운 물건일 때
      console.log('새로운 상품입니다.')
      setCartItems([...cartItems, { itemId, quantity : 1 }])
    }
  }



  const removeCart = (itemId) => {
    setCartItems(cartItems.filter((el)=> el.itemId !== itemId))
  }


  
  const Quantity = (itemId, quantity) => {
    const itemList = cartItems.filter((el) => el.itemId === itemId)[0] // 추가될 아이템
    
    const index = cartItems.indexOf(itemList) // 아이템 추가하기

    const cartItem = {
      "itemId" : itemId,
      "quantity" : quantity
    }

    setCartItems([...cartItems.slice(0, index), 
      cartItem,
  ...cartItems.slice(index + 1, cartItems.length)])
  }


  return (
    <Router>
      <Nav cartItems={cartItems} />
      <Switch>
        <Route exact={true} path="/">
          <ItemListContainer items={items} addCart={addCart} />
        </Route>
        <Route path="/shoppingcart">
          <ShoppingCart cartItems={cartItems} items={items} removeCart={removeCart} Quantity={Quantity}/>
        </Route>
      </Switch>
    </Router>
  );
}

export default App;




components/Nav.js


Nav는 App.js에서 props ( cartItems ) 를 전달 받으며 그 값을 장바구니 우측의 span 태그 사이에 삽입


import React from 'react';
import { Link } from 'react-router-dom';

function Nav({ cartItems }) {

  return (
    <div id="nav-body">
      <span id="title">
        <img id="logo" src="../logo.png" alt="logo" />
        <span id="name">CMarket</span>
      </span>
      <div id="menu">
        <Link to="/">상품리스트</Link>
        <Link to="/shoppingcart">
          장바구니<span id="nav-item-counter">{cartItems.length}</span>
        </Link>
      </div>
    </div>
  );
}

export default Nav;




Pages/ItemlistContainer


addCart를 props로 추가로 받아왔으니 items 옆에 addCart를 추가해준 다음 handle click 함수를 수정해준다


import React from 'react';
import Item from '../components/Item';

function ItemListContainer({ items, addCart }) {
  
  return (
    <div id="item-list-container">
      <div id="item-list-body">
        <div id="item-list-title">쓸모없는 선물 모음</div>
        {items.map((item, idx) => <Item item={item} key={idx} handleClick={() => addCart(item.id)} />)}
      </div>
    </div>
  );
}

export default ItemListContainer;




pages/ShoppingCart.js


App.js에서 내려받은 props --- addCart, removeCart를 추가해주고 handleQuantityChange와 handleDelete를 수정해준다


import React, { useState } from 'react'
import CartItem from '../components/CartItem'
import OrderSummary from '../components/OrderSummary'

export default function ShoppingCart({ items, cartItems, removeCart, Quantity }) {
  const [checkedItems, setCheckedItems] = useState(cartItems.map((el) => el.itemId))

  const handleCheckChange = (checked, id) => {
    if (checked) {
      setCheckedItems([...checkedItems, id]);
    }
    else {
      setCheckedItems(checkedItems.filter((el) => el !== id));
    }
  };

  const handleAllCheck = (checked) => {
    if (checked) {
      setCheckedItems(cartItems.map((el) => el.itemId))
    }
    else {
      setCheckedItems([]);
    }
  };

  const handleQuantityChange = (quantity, itemId) => { //장바구니에 담기 아이템 수량 조절
    Quantity(itemId, quantity)
  }

  const handleDelete = (itemId) => {
    setCheckedItems(checkedItems.filter((el) => el !== itemId))
    removeCart(itemId)
  }

  const getTotal = () => {
    let cartIdArr = cartItems.map((el) => el.itemId)
    let total = {
      price: 0,
      quantity: 0,
    }
    for (let i = 0; i < cartIdArr.length; i++) {
      if (checkedItems.indexOf(cartIdArr[i]) > -1) {
        let quantity = cartItems[i].quantity
        let price = items.filter((el) => el.id === cartItems[i].itemId)[0].price

        total.price = total.price + quantity * price
        total.quantity = total.quantity + quantity
      }
    }
    return total
  }

  const renderItems = items.filter((el) => cartItems.map((el) => el.itemId).indexOf(el.id) > -1)
  const total = getTotal()

  return (
    <div id="item-list-container">
      <div id="item-list-body">
        <div id="item-list-title">장바구니</div>
        <span id="shopping-cart-select-all">
          <input
            type="checkbox"
            checked={
              checkedItems.length === cartItems.length ? true : false
            }
            onChange={(e) => handleAllCheck(e.target.checked)} >
          </input>
          <label >전체선택</label>
        </span>
        <div id="shopping-cart-container">
          {!cartItems.length ? (
            <div id="item-list-text">
              장바구니에 아이템이 없습니다.
            </div>
          ) : (
              <div id="cart-item-list">
                {renderItems.map((item, idx) => {
                  const quantity = cartItems.filter(el => el.itemId === item.id)[0].quantity
                  return <CartItem
                    key={idx}
                    handleCheckChange={handleCheckChange}
                    handleQuantityChange={handleQuantityChange}
                    handleDelete={handleDelete}
                    item={item}
                    checkedItems={checkedItems}
                    quantity={quantity}
                  />
                })}
              </div>
            )}
          <OrderSummary total={total.price} totalQty={total.quantity} />
        </div>
      </div >
    </div>
  )
}




profile
세상은 넓고 배울건 많다

0개의 댓글