import React, { useState } from 'react';
import Nav from './components/Nav';
import ItemListContainer from './pages/ItemListContainer';
import './App.css';
import './variables.css';
import { BrowserRouter as Router, Routes, 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);
// cartItems={cartItems} setCartItems={setCartItems}을 props로 넘겨준다
return (
<Router>
<Nav />
<Routes>
<Route path="/" element={<ItemListContainer items={items} cartItems={cartItems} setCartItems={setCartItems}/>} />
<Route
path="/shoppingcart"
element={<ShoppingCart cartItems={cartItems} items={items} setCartItems={setCartItems}/>}
/>
</Routes>
<img
id="logo_foot"
src={`${process.env.PUBLIC_URL}/codestates-logo.png`}
alt="logo_foot"
/>
</Router>
);
}
export default App;
메인 화면에서 [장바구니 담기] 버튼을 누른 후, 장바구니 페이지로 이동하면 상품이 담겨있어야 합니다.
onClick={(e) => handleClick(e, item.id)
장바구니 담기 버튼이 실행될 시에 받는 인자
import React from 'react';
import Item from '../components/Item';
function ItemListContainer({ items, cartItems, setCartItems }) {
const handleClick = (e, id) => {
let newItem = cartItems
let num = cartItems.findIndex((e) => e.itemId === id) // x-> -1
if (num !== -1){
newItem[num].quantity++
setCartItems(newItem)
} else setCartItems([...newItem, {"itemId":id, "quantity":1}])
}
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={handleClick} />)}
</div>
</div>
);
}
export default ItemListContainer;
이건 findIndex
를 이용하면 된다는 걸 알았을 때.. 머리 싸매며 구현했던 코드
else {
setCartItems([...newItem,
{"itemId": id,
"quantity": 1}
])
}
원래 장바구니에 담겨있지 않던 아이템을 넣었을 때
새롭게 추가하는 방법이 잘 생각이 나지 않아서 애먹었던 부분이다.
그리고 처음에 for문
을 이용해서 추가했던 코드
function ItemListContainer({ items, cartItems, setCartItems}) {
const handleClick = (e, id) => { // 클릭을 하면 클릭한 값의 아이디를 가져옴
let newCartItem = {};
newCartItem.itemId = id;
newCartItem.quantity = 1;
for (let i = 0; i < cartItems.length; i++){
if (cartItems[i].itemId === id){ // 클릭한 상품과 현재 상품을 (id)비교, 있으면 +1 해서 리스트에 추가만 하고
setCartItems([...cartItems])
cartItems[i].quantity++
} else setCartItems([...cartItems, newCartItem]) // 없으면 새롭게 추가 (자동으로 1이되게..? -> 처음에 quantity = 1 로 설정)
}
}
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={handleClick} />)}
</div>
</div>
);
}
내비게이션 바에 상품 개수가 즉시 표시되어야 합니다.
<Router>
...
<Nav cartItems={cartItems}/>
...
</Router>
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;
장바구니 페이지에서 장바구니에 담긴 각 아이템의 개수를 변경할 수 있어야 합니다.
cartitem.js 에서
onChange={(e) => {
handleQuantityChange(Number(e.target.value), item.id)
}}
발견
처음에 handleQuantityChange 함수를
const handleQuantityChange = (quantity, itemId) => {
let idx = cartItems.findIndex((el) => el.itemId === itemId)
cartItems[idx].quantity = quantity
setCartItems(cartItems)
}
이렇게 했는데 바뀌지가 않았다..
페어분이 알려주셨는데 이게 참조값이라 얕은 복사
라서 상태 값을 잠시 저장만 한 것이라서 그런 거라고.. 이 실제 값을 메모리 공간에 저장하려면 깊은 복사
를 해야한다고 했다.
export default function ShoppingCart({ items, cartItems, setCartItems }) {
...
const handleQuantityChange = (quantity, itemId) => {
let newCartItems = [...cartItems]
let idx = cartItems.findIndex((el) => el.itemId === itemId)
newCartItems[idx].quantity = quantity
setCartItems(newCartItems)
}
...
}
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)])
}
const handleQuantityChange = (quantity, itemId) => {
Quantity(itemId, quantity)
}
장바구니 페이지에서 [삭제] 버튼을 누른 후, 해당 상품이 목록에서 삭제되어야 합니다.
cartitem.js 내 버튼 부분확인
<button className="cart-item-delete" onClick={() => {
handleDelete(item.id) }
}>삭제</button>
export default function ShoppingCart({ items, cartItems, setCartItems }) {
const handleDelete = (itemId) => {
setCheckedItems(checkedItems.filter((el) => el !== itemId))
setCartItems(cartItems.filter((el)=> el.itemId !== itemId))
}
...