์ด๋ค ์ก์ ์ ์ทจํ ๊ฒ์ธ์ง ์ ์ํด ๋์ ๊ฐ์ฒด์ ๋๋ค.
payload
์ ์ก๋๋ ๋ฐ์ดํฐ๋ฅผ ์๋ฏธํฉ๋๋ค. ๋ฐ์ดํฐ๋ฅผ ์ ์กํ ๋, ๋ค์ํ ์์๋ค์ ํจ๊ผ ๋ณด๋ด์ด, ๋ฐ์ดํฐ ์ ์ก์ ํจ์จ๊ณผ ์์ ์ฑ์ ๋ํ๊ฒ ๋ฉ๋๋ค. ์ด๋, ๋ณด๋ด๊ณ ์ ํ๋ ๋ฐ์ดํฐ ์์ฒด๋ฅผ ์๋ฏธํฉ๋๋ค.
Test case
Shopping Cart Actions
์ฝ๋ ์์ฑ ์ ์ ์์ฌํญ
actions/index.js
export const addToCart = (itemId) => { return { type: ADD_TO_CART, payload: { quantity: 1, itemId } } } export const removeFromCart = (itemId) => { return { //TODO // ์ ์ดํด๋์ค action ์์ ์ฐธ๊ณ type : REMOVE_FROM_CART, payload : { itemId } } } export const setQuantity = (itemId, quantity) => { return { //TODO type : SET_QUANTITY, payload : { quantity, itemId } } }
Dispatch์๊ฒ์ ์ ๋ฌ๋ฐ์ Action ๊ฐ์ฒด์ type ๊ฐ์ ๋ฐ๋ผ์ ์ํ๋ฅผ ๋ณ๊ฒฝ์ํค๋ ํจ์์ ๋๋ค.
Test Case
Item Reducer
์ฝ๋ ์์ฑ ์ ์ ์์ฌํญ
itemReducer.js
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 currentItem = state.cartItems.filter( el => el.itemId !== action.payload.itemId) return Object.assign({}, state, { cartItems: currentItem }) break; case SET_QUANTITY: let idx = state.cartItems.findIndex(el => el.itemId === action.payload.itemId) //TODO return { ...state, cartItems: [...state.cartItems.slice(0, idx), action.payload, ...state.cartItems.slice(idx + 1)] } break; default: return state; } }
Reducer๋ก Action์ ์ ๋ฌํด์ฃผ๋ ํจ์์ ๋๋ค. Dispatch์ ์ ๋ฌ์ธ์๋ก Action ๊ฐ์ฒด๊ฐ ์ ๋ฌ๋ฉ๋๋ค.
Test Case
Shopping Pages
์ฝ๋ ์์ฑ ์ ์ ์์ฌํญ
ItemListContainer.js
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('์ด๋ฏธ ์ถ๊ฐ๋ ์ํ์ ๋๋ค.')) } }
ShoppingCart.js
const dispatch = useDispatch(); const handleQuantityChange = (quantity, itemId) => { //TODO: dispatch ํจ์๋ฅผ ํธ์ถํ์ฌ ์ก์ ์ ์ ๋ฌํ์ธ์. dispatch(setQuantity(itemId, quantity)) } const handleDelete = (itemId) => { setCheckedItems(checkedItems.filter((el) => el !== itemId)) //TODO: dispatch ํจ์๋ฅผ ํธ์ถํ์ฌ ์ก์ ์ ์ ๋ฌํ์ธ์. dispatch(removeFromCart(itemId)) // ์นดํธ(์ฅ๋ฐ๊ตฌ๋)์์์ ์ญ์ ๋ ์์ดํ ์์ฒญ }
Action ๋ถ๋ถ๊ณผ Dispatch ๋ถ๋ถ์ ์ด๋์ ๋ ์ดํด๊ฐ ๋๊ณ ์ฝ๋ ์์ฑํ๋ ๋ฐ ๋ฌธ์ ๊ฐ ์์์ง๋ง, Reducer ๋ถ๋ถ์ ์์ฑํ ๋, ๋ฐฐ์ด ๊ฐ๋ ๊ณผ ์กฐ๊ธ ๋ฌ๋ผ ์์ฑํ๋๋ฐ ์๊ฐ์ด ๋ค์ ๊ฑธ๋ ธ๋ค. Object.assign์ ์ ์ฐ๋์ง, ํ์ํ ์ด์ ๋ ๋ฌด์์ธ์ง์ ๋ํด ๊ถ๊ธํ๋ค. ๋๋ต์ ์ธ ์ด์ ๋ ์ฐพ์์ง๋ง ์ ํํ๊ฒ ์ด์ ๋ ์์ง ๋ชป ํ์๋ค. ์ด ๋ถ๋ถ์ ์ข ๋ ํ์ต ํด์ผ๊ฒ ๋ค. ๊ทธ๋ฆฌ๊ณ Redux ๋ถ๋ถ์ ๋ฏธ๋ ํ๋ก์ ํธ์์๋ ์ฐ์ด๊ณ ์๊ธฐ ๋๋ฌธ์ ์ด๋ ํ ํ์์ ๋๊ณ ์๋ ๊ฑด์ง๋ ํ์ ํ ์ ์์ ๊ฒ ๊ฐ๋ค. ๊ทธ๋ฌ๋ฉด์ Redux์ ๋ํ ๋ด์ฉ์ ์ ์ดํดํ๋ฉด ๋์ง ์์๊น ์ถ๋ค. ๋ฏธ๋ ํ๋ก์ ํธ๋ ์ด์ฌํ ๋ง๋ค์ด๋ณด์.