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>
)
}