Code๊ฐ๋ฐ์ผ์ง
[Redux] Cmarket Redux
Minhhk
2022. 12. 30. 16:14
๐ ์ด์ ์ Cmarket Hooks ๋ก ๋ง๋ค์๋ ์ฅ๋ฐ๊ตฌ๋๋ฅผ Redux๋ก!!
ํ ์คํธ ์ผ์ด์ค๋ ์ด๋ ๋ค.
์์์ ๋ถํฐ ํ๋ํ๋ ๊ตฌํ ํด๋ณด์!
์ ์ฒด์ ์ผ๋ก๋ ๊ตฌํ๋์ด ์์๊ณ ,
๋ถ๋ถ์ ์ผ๋ก ๊ตฌํํด์ผํ ๋ถ๋ถ์?!
//TODO
๋ฅผ ์ฐพ์ ํด๋ณด์
- Dispatchํจ์์ ์ ๋๊ฒจ์ค ์ธ์ Action์ ์์ฑํด๋ณด์!
- Reducerํจ์์ ์ ๋ฌํ Dispatch ํจ์๋ฅผ ์์ฑ
- ํ ์คํธ ์ผ์ด์ค๊ฐ ์ ํต๊ณผ๋์๋ค๋ฉด, store ์ํ๊ฐ ์ ๋ณ๊ฒฝ ๋ ๊ฒ์ด๋ค~
addToCart๋ ์์ฑ์ด ๋์ด ์์๋ค.
์ฐธ๊ณ ํ์ฌ removeFromCart ์ setQuantity ์์ฑ
actions/index.js
// action types
export const ADD_TO_CART = "ADD_TO_CART";
export const REMOVE_FROM_CART = "REMOVE_FROM_CART";
export const SET_QUANTITY = "SET_QUANTITY";
export const NOTIFY = "NOTIFY";
export const ENQUEUE_NOTIFICATION = "ENQUEUE_NOTIFICATION";
export const DEQUEUE_NOTIFICATION = "DEQUEUE_NOTIFICATION";
// actions creator functions
export const addToCart = (itemId) => {
return {
type: ADD_TO_CART,
payload: {
quantity: 1,
itemId: itemId
}
}
}
export const removeFromCart = (itemId) => {
return {
//TODO
type: REMOVE_FROM_CART,
payload: {
itemId : itemId
//itemId
}
}
}
export const setQuantity = (itemId, quantity) => {
return {
//TODO
type: SET_QUANTITY,
payload: {
quantity: quantity,
itemId: itemId
}
}
}
export const notify = (message, dismissTime = 5000) => dispatch => {
const uuid = Math.random()
dispatch(enqueueNotification(message, dismissTime, uuid))
setTimeout(() => {
dispatch(dequeueNotification())
}, dismissTime)
}
export const enqueueNotification = (message, dismissTime, uuid) => {
return {
type: ENQUEUE_NOTIFICATION,
payload: {
message,
dismissTime,
uuid
}
}
}
export const dequeueNotification = () => {
return {
type: DEQUEUE_NOTIFICATION
}
}
const dispatch = useDispatch();
๋ฅผ ์ฌ์ฉํ์ฌ dispatch() ์์ฑ!
→ ์ฅ๋ฐ๊ตฌ๋ ์ถ๊ฐ → ์์ดํ ์์ด๋ ์ถ๊ฐ
๐ dispatch(addToCart(item.id))
pages/ItemListContainer.js
import React from 'react';
import { addToCart, notify } from '../actions/index';
import { useSelector, useDispatch } from 'react-redux';
import Item from '../components/Item';
function ItemListContainer() {
const state = useSelector(state => state.itemReducer);
const { items, cartItems } = state;
const dispatch = useDispatch();
const handleClick = (item) => {
if (!cartItems.map((el) => el.itemId).includes(item.id)) {
//TODO: dispatch ํจ์๋ฅผ ํธ์ถํ์ฌ ์์ดํ
์ถ๊ฐ์ ๋ํ ์ก์
์ ์ ๋ฌํ์ธ์.
dispatch(addToCart(item.id))
dispatch(notify(`์ฅ๋ฐ๊ตฌ๋์ ${item.name}์ด(๊ฐ) ์ถ๊ฐ๋์์ต๋๋ค.`))
}
else {
dispatch(notify('์ด๋ฏธ ์ถ๊ฐ๋ ์ํ์
๋๋ค.'))
}
}
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(item)
}} />)}
</div>
</div>
);
}
export default ItemListContainer;
pages/ShoppingCart.js
const handleQuantityChange = (quantity, itemId) => {
//TODO: dispatch ํจ์๋ฅผ ํธ์ถํ์ฌ ์ก์
์ ์ ๋ฌํ์ธ์.
dispatch(setQuantity(itemId, quantity))
}
const handleDelete = (itemId) => {
setCheckedItems(checkedItems.filter((el) => el !== itemId))
//TODO: dispatch ํจ์๋ฅผ ํธ์ถํ์ฌ ์ก์
์ ์ ๋ฌํ์ธ์.
dispatch(removeFromCart(itemId))
}
Object.assign({}, state, {
cartItems: [...state.cartItems, action.payload]
})
๊ฐ์ฒด ๋ณต์ ์
→
const obj = { a: 1 };
const copy = Object.assign({}, obj);
console.log(copy); // { a: 1 }
๊ฐ์ฒด ๋ณํฉ ์ด์ฉ
→
const o1 = { a: 1, b: 1, c: 1 };
const o2 = { b: 2, c: 2 };
const o3 = { c: 3 };
const obj = Object.assign({}, o1, o2, o3);
console.log(obj); // { a: 1, b: 2, c: 3 }
Object.assign() - JavaScript | MDN
Object.assign() ๋ฉ์๋๋ ์ถ์ฒ ๊ฐ์ฒด๋ค์ ๋ชจ๋ ์ด๊ฑฐ ๊ฐ๋ฅํ ์์ฒด ์์ฑ์ ๋ณต์ฌํด ๋์ ๊ฐ์ฒด์ ๋ถ์ฌ๋ฃ์ต๋๋ค. ๊ทธ ํ ๋์ ๊ฐ์ฒด๋ฅผ ๋ฐํํฉ๋๋ค.
developer.mozilla.org
case ADD_TO_CART:
case REMOVE_FROM_CART:
case SET_QUANTITY:
์์ฑ!!!
pages/reducers/itemReducer.js
import { REMOVE_FROM_CART, ADD_TO_CART, SET_QUANTITY } from "../actions/index";
import { initialState } from "./initialState";
const itemReducer = (state = initialState, action) => {
switch (action.type) {
case ADD_TO_CART:
//TODO
return Object.assign({}, state, {
// ํค : ๊ฐ
cartItems: [...state.cartItems, action.payload],
});
break;
case REMOVE_FROM_CART:
//TODO
let remove = state.cartItems.filter(
(el) => el.itemId !== action.payload.itemId
);
return Object.assign({}, state, {
cartItems: remove,
});
break;
case SET_QUANTITY:
// TODO
//! ์นดํธ์์ดํ
๋ฐฐ์ด ์ธ๋ฑ์ค
let targetIdx = state.cartItems.findIndex(
(el) => el.itemId === action.payload.itemId
);
return {
...state,
cartItems: state.cartItems.map((el, idx) =>
idx === targetIdx ? action.payload : el
),
};
break;
default:
return state;
}
};
export default itemReducer;
๊ฒฐ๊ณผ ํ๋ฉด!