
Section3 Unit4 [React] ์ํ ๊ด๋ฆฌ - ๊ณผ์  Cmarket Redux
โญ๏ธ ๊ณผ์ . Cmarket Redux
โ๏ธ Bare Minimum Requirement
โ Action, Reducer๋ฅผ ์ง์  ์์ฑํ๊ณ ํ ์คํธ ์ผ์ด์ค๋ฅผ ํต๊ณผํฉ๋๋ค.
โ๏ธ ๊ณผ์  ๊ตฌํ
๐ ๋ฆฌ๋์ค์ ๋ฐ์ดํฐ ํ๋ฆ Action → Dispatch → Reducer → Store
1. ์ํ๊ฐ ๋ณ๊ฒฝ๋์ด์ผ ํ๋ ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๋ฉด, ๋ณ๊ฒฝ๋ ์ํ์ ๋ํ ์ ๋ณด๊ฐ ๋ด๊ธด Action ๊ฐ์ฒด๊ฐ ์์ฑ
2. Action ๊ฐ์ฒด๋ Dispatch ํจ์์ ์ธ์๋ก ์ ๋ฌ
3. Dispatch ํจ์๋ Action ๊ฐ์ฒด๋ฅผ Reducer ํจ์๋ก ์ ๋ฌ
4. Reducer ํจ์๋ Action ๊ฐ์ฒด์ ๊ฐ์ ํ์ธํ๊ณ , ๊ทธ ๊ฐ์ ๋ฐ๋ผ ์ ์ญ ์ํ ์ ์ฅ์ Store์ ์ํ๋ฅผ ๋ณ๊ฒฝ
5. ์ํ๊ฐ ๋ณ๊ฒฝ๋๋ฉด React๋ ํ๋ฉด์ ๋ค์ ๋ ๋๋ง
โจ handleClick, handleQuantityChange, handleDelete
์ฅ๋ฐ๊ตฌ๋ ๋ด๊ธฐ or ์๋ ๋ณ๊ฒฝ or ์ญ์  ๋ฒํผ์ ๋๋ ์ ๋
// ItemListContainer.js
// ๐ ์ฅ๋ฐ๊ตฌ๋ ๋ด๊ธฐ ๋ฒํผ์ ๋๋ ์ ๋
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 handleQuantityChange = (quantity, itemId) => {
  //TODO: dispatch ํจ์๋ฅผ ํธ์ถํ์ฌ ์ก์
์ ์ ๋ฌํ์ธ์.
  dispatch(setQuantity(itemId, quantity))
}
// ๐ ์ญ์  ๋ฒํผ์ ๋๋ ์ ๋
const handleDelete = (itemId) => {
  setCheckedItems(checkedItems.filter((el) => el !== itemId))
  //TODO: dispatch ํจ์๋ฅผ ํธ์ถํ์ฌ ์ก์
์ ์ ๋ฌํ์ธ์.
  dispatch(removeFromCart(itemId))
}// 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";
// actions creator functions
export const addToCart = (itemId) => {
  return {
    type: ADD_TO_CART,
    payload: {
      quantity: 1,
      itemId
    }
  }
}
export const removeFromCart = (itemId) => {
  return {
    //TODO
    type: REMOVE_FROM_CART,
    payload: {
      itemId
    }
  }
}
export const setQuantity = (itemId, quantity) => {
  return {
    //TODO
    type: SET_QUANTITY,
    payload: {
      itemId,
      quantity
    }
  }
}// 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] })
      
      // Spread Syntax
      // return { ...state, cartItems: [...state.cartItems, action.payload] }
    case REMOVE_FROM_CART:
      //TODO
      const updatedItems = state.cartItems.filter((item) => item.itemId !== action.payload.itemId);
      console.log(action.payload.itemId) // ์ญ์ ํ  ์ ํ์ itemId
      console.log("updatedItems", updatedItems) // ์ ํ์ด ์ญ์ ๋ ํ์ ๋ฆฌ์คํธ
      return Object.assign({}, state, { cartItems: updatedItems })
    case SET_QUANTITY:
      let idx = state.cartItems.findIndex(el => el.itemId === action.payload.itemId);
      
      //TODO
      return Object.assign({}, state, {
        cartItems: [...state.cartItems.slice(0, idx), action.payload, ...state.cartItems.slice(idx + 1)]
      })
      // Spread Syntax
      /*
      return { 
        ...state,
        cartItems: [...state.cartItems.slice(0, idx), action.payload, ...state.cartItems.slice(idx + 1)]
      }
      */
      
      // map
      /*
      return {
        ...state,
        cartItems: state.cartItems.map((el, index) => index === idx ? action.payload : el)
      }
      */
      // map (idx ์ฌ์ฉ X)
      /*
      return {
        ...state,
        cartItems: state.cartItems.map((el) => el.itemId === action.payload.itemId ? action.payload : el)
      }
      */
     
     
    default:
      return state;
  }
}
export default itemReducer;
Reducer์ Immutability(๋ถ๋ณ์ฑ)
Redux์ state ์ ๋ฐ์ดํธ๋ immutableํ ๋ฐฉ์์ผ๋ก ๋ณ๊ฒฝํด์ผ ํ๊ธฐ ๋๋ฌธ์ Reducer ํจ์๋ฅผ ์์ฑ์ ์ฃผ์ํด์ผ ํ๋ค.
 immutableํ ๋ฐฉ์์ผ๋ก state๋ฅผ ๋ณ๊ฒฝํ๊ธฐ ์ํด์๋ Object.assign() ๋๋ spread syntax๋ฅผ ์ฌ์ฉํ  ์ ์๋ค.
๐ ์ค๋์ ํ๊ณ
์ด๋ ๊ฒ ํ ์ฃผ๊ฐ ๋ฒ์จ ๋์ด ๋ฌ๋ค. ์ด๋ฒ ์ฃผ๋ ๋ฆฌ์กํธ๋ก custom component ๋ง๋ค๊ธฐ๋ถํฐ ๋ฆฌ๋์ค๊น์ง, ๋ฐฐ์์ผ ํ ๊ฒ๋ค๋ ๋ง์๊ณ , ๋ฐฐ์ธ ๊ฒ์ด ๋ง์ผ๋ ์ ๋ฆฌํด์ผ ํ ๋ถ๋ถ๋ ๋ง์๋ค. ๊พธ์คํ ์ต๊ด์ฒ๋ผ ํ๋ ๋ธ๋ก๊น ๋ ์ ๋๋ก ๋ชปํ๊ณ , ์์ง ๋ ธ์  ์ ๋ฆฌ๋ ์ ๋๋ก ๋ชปํด์ ์ฃผ๋ง๋์ ์ด์ฌํ ์ ๋ฆฌ๋ฅผ ํด๋ณผ ์๊ฐ์ด๋ค. ๋ถํธ์บ ํ TIL ๋ธ๋ก๊น ์ ์ฌ์ค ๋์ค์ ๋ฉด์  ์๋ฆฌ์์ ์ฑ์ค์ฑ์ ์กฐ๊ธ์ด๋๋ง ๋ณด์ฌ์ฃผ๊ธฐ ์ํด ์์ํ ์ด์ ๋ ์์๋๋ฐ, ์ง๊ธ์ ์ฝ๊ฐ ์ต๊ด์ฒ๋ผ ๋ญ๋ผ๋ ๊ธฐ๋กํด๋๋๋ฐ ์์๋ฅผ ๋๋ ๊ฒ ๊ฐ๋ค. ๋ธ๋ก๊ทธ๋ณด๋ค๋ ๋ ธ์ ์ ๊ฑฐ์ ๋ชจ๋ ๊ฒ์ ๊ธฐ๋กํด๋์ด์ ์ธ์ง ๋ธ๋ก๊ทธ์ ๋๋ฌด ๋ง์ ์๊ฐ์ ์์ง๋ ์์ผ๋ ค ํ๊ณ ์๋ค. (๊ทธ๋๋ ์ญ์ ๋จ๋ค์ด ๋ณผ ์ ์๋, ๋ฐํ์ด ๋๋ ๊ธ์ด๋ผ ์ ๊ฒฝ์ด ์ฐ์ด๋ ๊ฑด ๋ง๋๋ฏ!) ์ฌํผ ๊ณต๋ถํ ๋ด์ฉ์ ์ ๋ฆฌํ๊ณ , ๊ธฐ๋กํด๋๋๊ฑด ์ ๋ง ์ข์ ์ต๊ด ๊ฐ๋ค. ํ์ง๋ง ์ด๊ฒ๋ ๋๋ฆ ์๊ฐ์ด ๊ฑธ๋ฆฌ๋ ์์ ์ด๋ผ ์ ๋ฆฌํ ๋ถ๋ถ์ ์ ๋ฆฌํ๊ณ , ์ฐ์ ๋์ด๊ฐ ๋ถ๋ถ์ ํค์๋๋ผ๋ ์จ๋๋๊ฒ ์ข์ ๊ฒ ๊ฐ๋ค๋ ์๊ฐ์ด ๋ค์๋ค. ๊ทธ๋๋ ๋ ธ์ ์ ์ ๋ฆฌ๋ฅผ ํด๋๋ฉด ํ์ํ ๋ ์ธ์ ๋ ์ง ๋ฐ๋ก ๊ฒ์ํด์ ์ฐพ์ ์๊ฐ ์๋ค๋ ์ ์ ์ฅ์ ์ด๋ค.
์ฌํผ ๋๋ ์์ง ๋ฆฌ๋์ค๋ฅผ ํ์ ํ๋ ์ค์ด๋ค. ์ค๋ ๋ง์  ๊ฐ์๋ฅผ ๋ณด๊ณ , ๊ณผ์ ๋ฅผ ๋ค์ ํ ๋ฒ ํด๋ด์ผ๊ฒ ๋ค.
๐๏ธ 23.6.25 SUN
๋ฆฌ๋์ค๋ฅผ ์ฐจ๊ทผ์ฐจ๊ทผ ๋ค์ ๊ณต๋ถํด๋ณด๊ณ ๊ณผ์ ๋ฅผ ๋ค์ ๊ตฌํํด๋ณด์๋ค. ๋ฆฌ๋์ค๊ฐ ์คํ๋๋ ๋ก์ง๊ณผ, ์ฝ๋๋ฅผ ์์ฑํ๋๊ฒ ์ต์์น ์์์ ์ด๋ ค์ ๋ ๊ณผ์ ๊ฐ ์ด๋ฒ์ ํจ์ฌ ์์ํ๊ฒ ๋๊ปด์ ธ์ ๊ธ๋ฐฉ ์์ฑํ ์ ์์๊ณ , ์ดํด๋ ํจ์ฌ ์๋๋ ๋ฏ ํ๋ค. ํ์ต์ฐจ์์์ ์ ๊ณต๋ ์ฝ๋ ์ค ์ด๋ฏธ ๋๋์ด์ง ํด๋๊ตฌ์กฐ์ ์์ฑ๋์ด์ ธ ์๋ ์ผ๋ถ ์ฝ๋๋ฅผ ๋ณด๋ฉฐ ๋ถํธํจ๋ ๋๊ผ๋ค. ํด๋๊ตฌ์กฐ๊ฐ ์ฌ๋ฌ๊ฐ๋ก ๋๋ ์ง๊ณ , ๋ฐ๋ณต์ ์ธ ์ฝ๋๊ฐ ์๊ธด๋ค๋ ๊ฒ์ด ๋ฌด์์ธ์ง ์ดํด๊ฐ ๋์๊ณ , ์ด๋ฌํ ๋ถ๋ถ๋ค์ ๊ฐ์ ํ์ฌ ๋ฆฌ๋์ค๋ฅผ ์ข ๋ ํธํ๊ฒ ์ฌ์ฉํ ์ ์๋ ๋ฐฉ๋ฒ์ด Redux Toolkit์ ์ด์ฉํ๋ ๊ฒ์ด๋ผ๊ณ ํ๋ ๊ฒ ๊ฐ๋ค. ์ด์  ๋๋์ด Redux Toolkit๋ ๋ณด๋ฌ ๊ฐ์ผ๊ฒ ๋ค..๐
 
									
								 
									
								 
									
								