
๋ฏธ์์ฑ์ Cmarket์ ๊ตฌ์ฑํ๋ React์ฝ๋๊ฐ ์๋ค. ์ด ์ฝ๋๋ฅผ ๋ง์ ์์ฑํด์ ์์ฑ๋ market์ ๊ตฌํํ๋ ๊ฒ์ด ๋ชฉํ๋ค.
<ํ์ด์ง ๊ด๋ จ ์ปดํฌ๋ํธ>
App.js : Cmarket์์ ์ต์์ ์ปดํฌ๋ํธ ์ด ์์์ Items์ carItems์ ์ํ๊ฐ ๋ค์ด์๋ค.ItemListContainer.js : App.js์ ์์ ์ปดํฌ๋ํธ๋ก ์ํ ๋ฆฌ์คํธ ํ์ด์ง๋ฅผ ๋ํ๋ด๋ ์ปดํฌ๋ํธShoppingCart.js : App.js์ ์์ ์ปดํฌ๋ํธ๋ก ์ฐ ๋ชฉ๋ก ๋ฆฌ์คํธ ํ์ด์ง๋ฅผ ๋ํ๋ด๋ ์ปดํฌ๋ํธ<ํ์ด์ง ๋ด๋ถ ์ปดํฌ๋ํธ>
Nav.js : App.js์ ์์ ์ปดํฌ๋ํธ๋ก ๊ฐ ํ์ด์ง ์ ๋ค๋น๊ฒ์ด์
์ ๋ํ๋ด๋ ์ปดํฌ๋ํธCartItem.js : ShoppingCart.js์ ์์ ์ปดํฌ๋ํธ๋ก ์ํ์ ๋ํ๋ด๋ ์ปดํฌ๋ํธItem.js : ItemListContainer.js์ ์์ ์ปดํฌ๋ํธ๋ก ์ํ์ ๋ํ๋ด๋ ์ปดํฌ๋ํธOrderSummary.js : ShoppingCart.js์ ์์ ์ปดํฌ๋ํธ๋ก ์ํ์ ์ข
ํฉ์ ์ผ๋ก ํ์ํด์ฃผ๋ ์ปดํฌ๋ํธstate.js : ์ํ๋ค์ดitems์ cartItems๋ก ๋ฐฐ์ด์ ํํ๋ก ๊ฐ์ฒด ์์ ๋ด๊ฒจ์๋ ์ผ์ข
์ DB// state.js
export const initialState =
{
"items": [
{
"id": 1,
"name": "๋
ธ๋ฅธ์ ๋ถ๋ฆฌ๊ธฐ",
"img": "../images/egg.png",
"price": 9900
},
{
"id": 2,
"name": "2020๋
๋ฌ๋ ฅ",
"img": "../images/2020.jpg",
"price": 12000
},
{
"id": 3,
"name": "๊ฐ๊ตฌ๋ฆฌ ์๋",
"img": "../images/frog.jpg",
"price": 2900
},
{
"id": 4,
"name": "๋ฏ์ด์จ ๋ณด๋๋ธ๋ญ",
"img": "../images/block.jpg",
"price": 4900
},
{
"id": 5,
"name": "์นผ๋ผ ๋ฆฝ์คํฑ",
"img": "../images/lip.jpg",
"price": 2900
},
{
"id": 6,
"name": "์์ด ์์ฆ",
"img": "../images/fish.jpg",
"price": 3900
},
{
"id": 7,
"name": "์ฐ์ปด ๋งคํธ",
"img": "../images/welcome.jpg",
"price": 6900
},
{
"id": 8,
"name": "๊ฐ์ ๋ชจ์",
"img": "../images/hat.jpg",
"price": 9900
}
],
"cartItems": [
{
"itemId": 1,
"quantity": 1
},
{
"itemId": 5,
"quantity": 7
},
{
"itemId": 2,
"quantity": 3
}
]
}
์ฐ๋ฆฌ๋ ์ง๊ธ ๊น์ง ์๋ฒ๋ฅผ ํตํ ๋ผ์ฐํ ์ ๋ฐฐ์ ๋ค. ์ง๊ธ ์ด ํ์ด์ง์์๋ ์๋ฒ๋ฅผ ํตํ์ง ์๊ณ ํด๋ผ์ด์ธํธ์์ ๋ผ์ฐํ ์ ์ค์ํ๋ ค๊ณ ํ๋ค. ๊ทธ ์ ์ ๋ค์ ํ๋ฒ ๋ผ์ฐํ ์ด ๋ฌด์์ธ๊ฐ? ๋ฅผ ์ง๊ณ ๋์ด๊ฐ์.
๋ผ์ฐํ : URL ์กฐ๊ฑด์ ๋ฐ๋ฅธ ๋ถ๊ธฐ๋ฅผ ๋๋๋ ๊ฒ
์๋ฒ๋ฅผ ํตํด์ ๋ผ์ฐํ ์ ๋๋๋ ๊ฒ์ ์ด์ ์ ์์๋ณด์๋ค. ๊ทธ๋ ๋ค๋ฉด Client Side Routing๋ ์ด๋ป๊ฒ ๊ตฌํํ ๊น? ์๋ ์ฝ๋๋ฅผ ํตํด ์ดํด๋ณด์.
return (
<Router>
<Nav />
<Switch>
<Route exact={true} path="/">
<ItemListContainer items={items} />
</Route>
<Route path="/shoppingcart">
<ShoppingCart cartItems={cartItems} items={items} />
</Route>
</Switch>
</Router>
);
์ ์ฝ๋๋ App.js ๋ด์์ ์ต์ข
์ ์ผ๋ก ํ๋ฉด์ ์ถ๋ ฅํ๋ ๋ฆฌํด ๊ฐ์ ๋ณด์ฌ์ฃผ๋ ๊ฒ์ด๋ค. ์ฝ๋๋ฅผ ์ดํด๋ณด๋ฉด Router, Switch, Route๋ก ๊ตฌ๋ถ์ ์ง์ด์ค๋๋ค.
๋ผ์ฐํฐ๊ฐ
/๋ฉด ItemListContainer ์ปดํฌ๋ํธ๋ฅผ ๋ณด์ฌ์ฃผ๊ณ/shoppingcart๋ฉด Soppingcart ์ปดํฌ๋ํธ๋ฅผ ์ถ๋ ฅํด์ค๋ค.
๊ทธ๋ ๋ค๋ฉด ์ด ๊ฒฝ๋ก๋ ์ด๋ป๊ฒ ํด์ ๋๋ ํ์ํ ์ ์๋๊ฐ ๊ทธ๊ฑด Nav.js๋ฅผ ์ดํด๋ณด๋ฉด ๋๋ค.
function Nav() {
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">0</span>
</Link>
</div>
</div>
);
}
์ ์ฝ๋์์ Link ์ปดํฌ๋ํธ์ to์์ฑ์ ํตํด์ ํด๋ฆญ์ ๋ผ์ฐํฐ๊ฐ ๋ณ๊ฒฝ๋๋๋ก ์ฑ์ ํ ์ ์๋ค.
๋จผ์ ํ์ํ ๊ฒ์ App.js์ ์ํ๋ฆฌ์คํธ์ state์ ์นดํธ๋ฆฌ์คํธ์ state๋ฅผ ์์ฑํ๊ณ ๊ทธ state๋ฅผ ๋ค๋ฃฐ ์ ์๋ ํจ์๋ฅผ Hook์ ํตํด์ ์์ฑํ๋ค.
// App.js
// initialState๋ import๋ฅผ ํตํด์ state์ ์๋ ๊ฐ์ ๋ฐ์์จ ๊ฒ์ด๋ค.
function App() {
const [items, setItems] = useState(initialState.items);
const [cartItems, setCartItems] = useState(initialState.cartItems);
return (
...
}
์ด ํ Item ์์ ์๋ ์ฅ๋ฐ๊ตฌ๋ ๋ด๊ธฐ ๋ฒํผ์ ํด๋ฆญํ๋ฉด ์ฅ๋ฐ๊ตฌ์น์ ์ํ์ด ์ถ๊ฐ๋๊ณ Nav ์ปดํฌ๋ํธ์ ์ํ์ ๊ฐฏ์๊ฐ ์
๋ฐ์ดํธ ๋๋๋ก ์ฝ๋๋ฅผ ์์ฑํ๋ฉด ๋๋ค.
// App.js
function App() {
const [items, setItems] = useState(initialState.items);
const [cartItems, setCartItems] = useState(initialState.cartItems);
const addToCart = (itemId) => {
const found = cartItems.filter((el) => el.itemId === itemId)[0]
// ์ธ์๋ก ๋ฐ์ itemId์ ์ํ์ด ์ด๋ฏธ cartItems์ ์์ผ๋ฉด ๊ทธ ์ํ์ found์ ํ ๋นํด์ค๋ค.
if(found) { // found๊ฐ ์์ผ๋ฉด ์ฆ, ์ด๋ฏธ ์นดํธ๋ชฉ๋ก์ ์๋ ๊ฒ์ด๋ฉด
setQuantity(itemId, found.quantity + 1)
//์ํ๋ฆฌ์คํธ์ ์ถ๊ฐํ๋ ๊ฒ์ด ์๋ ๊ทธ ์ํ์ quantitiy๊ฐ์ ์ฆ๊ฐ์ํจ๋ค.
}else{ // found๊ฐ ์์ผ๋ฉด ์ฆ, ์นดํธ๋ชฉ๋ก์ ์๋ ์ํ์ด๋ฉด
setCartItems([...cartItems, {itemId, quantity: 1}])
//์ํ ๋ชฉ๋ก์ ํด๋น ์ํ์ ์์ด๋์ ์๋์ ์ถ๊ฐํด์ค๋ค.
}
}
const setQuantity = (itemId, quantity) => { //ํด๋น ์์ดํ
์์ด๋์ ์๋์ ์
๋ ฅ ๋ฐ๋๋ค.
const found = cartItems.filter((el) => el.itemId === itemId)[0] //ํด๋น ์์ดํ
ํ ๋น
const idx = cartItems.indexOf(found) // ํด๋น ์์ดํ
์ ์์ฐจ ๊ฐ ํ ๋น
const cartItem = { //ํด๋น ์์ดํ
์ ์๋์ ๋ณ๊ฒฝํด์ ๋ค์ ์ ์ํ๋ค.
itemId,
quantity
}
setCartItems([...cartItems.slice(0, idx), cartItem, ...cartItems.slice(idx + 1)])
//ํด๋น ์์ดํ
์ ์์น์ ์๋์ ๋ณ๊ฒฝํด์ ๋ค์ ์ ์ํ ์์ดํ
์ ๋ผ์ ๋ฃ์ด์ ์ฌ ์ ์ํ๋ค.
}
return (
...
<Nav cartItems={cartItems}/>
...
<ItemListContainer items={items} handleAdd={addToCart} />
// addToCart ํจ์๋ฅผ ItemListContainer ์ปดํฌ๋ํธ์ props๋ก ์ ๋ฌํด์ค๋ค.
...
}
// ItemListContainer.js
function ItemListContainer({ items, handleAdd }) {
const handleClick = () => handleAdd(item.id)
// handleClick์ ์คํํ๋ฉด ํด๋น ์์ดํ
์ id ๊ฐ์ ๊ฐ์ง๊ณ handleAddํจ์๋ฅผ ์คํํ๋ค.
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>
);
}
// Item.js
function Item({ item, handleClick }) {
return (
<div key={item.id} className="item">
<img className="item-img" src={item.img} alt={item.name}></img>
<span className="item-name">{item.name}</span>
<span className="item-price">{item.price}</span>
<button className="item-button" onClick={(e) => handleClick(e, item.id)}>์ฅ๋ฐ๊ตฌ๋ ๋ด๊ธฐ</button>
</div>
)
}
์ ์ฝ๋๋ฅผ ์์ฑํ๊ณ ์์ดํ
๋ฆฌ์คํธ์ ์๋ ์ํ์ ์ฅ๋ฐ๊ตฌ๋ ๋ด๊ธฐ๋ฅผ ํด๋ฆญํ๋ฉด cartItems๋ฐฐ์ด์ ํด๋น ์์ดํ
์ด ๋ด๊ธฐ๊ณ ์ด๋ฏธ ํด๋น ์์ดํ
์ด ์๋ค๋ฉด ์๋์ ๋๋ฆด ๊ฒ์ด๋ค.
๊ทธ๋ฆฌ๊ณ Nav์ปดํฌ๋ํธ์ ํ์๋๋ ์ํ์ ๊ฐฏ์ ๋ํ ๋ณ๊ฒฝ๋์ด์ผ ํ ๊ฒ์ด๋ค.
// Nav.js
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>
);
}
์ฅ๋ฐ๊ตฌ๋ ์์ ํ์๋๋ ์ํ์ ๊ฐฏ์๋ cartItems ๋ฐฐ์ด์ ๊ฐ์ฒด์ ํํ๋ก ๋ด๊ฒจ ์๋ค. ๋ค์ ๋งํด์ cartItems์ ๊ธธ์ด๊ฐ ๊ฒฐ๊ตญ ๋ด๊ฒจ์๋ ์ํ์ ๊ฐฏ์๊ฐ ๋๋ค๋ ๋ง์ด๋ค. ๋๋ฌธ์ ๋ค์๊ณผ ๊ฐ์ด ์์ฑํด์ฃผ๋ฉด ๋๋ค.
์ฅ๋ฐ๊ตฌ๋๋ก ๋ถํฐ ์ํ์ ์ ๊ฑฐํ๋ ค๋ฉด CartItem์ ์๋ ์ญ์ ๋ฒํผ ์ ํด๋ฆญํ์ ๋ cartItems์ ๋ฐฐ์ด์์ ํด๋น ์ํ์ด ์ฌ๋ผ์ง๊ฒ ํ๋ฉด ๋๋ค. ์ด๋ฅผ ๊ตฌํํ๋ ๋ค์ ์ฝ๋๋ฅผ ์ดํด๋ณด์
// App.js
function App() {
const [items, setItems] = useState(initialState.items);
const [cartItems, setCartItems] = useState(initialState.cartItems);
...
const removeFromCart = (itemId) => {
setCartItems(cartItems.filter((el) => el.itemId !== itemId))
// ์ธ์๋ก ๋ฐ์ itemId์ ์ผ์นํ์ง ์๋ ๊ฐ๋ค์ ํํฐ๋งํด์ cartItems๋ฅผ ๋ค์ ํ ๋นํ๋ค.
}
return (
...
<ShoppingCart cartItems={cartItems} items={items} handleDelete = {removeFromCart}/>
...
)
}
// ShoppingCart.js
function ShoppingCart({ items, cartItems, handleDelete: onDelete })