๊ด€๋ฆฌ ๋ฉ”๋‰ด

Daily Front_Minhhk

[Redux] Cmarket Redux ๋ณธ๋ฌธ

Code๊ฐœ๋ฐœ์ผ์ง€

[Redux] Cmarket Redux

Minhhk 2022. 12. 30. 16:14
 ๐Ÿ“Œ ์ด์ „์— Cmarket Hooks ๋กœ ๋งŒ๋“ค์—ˆ๋˜ ์žฅ๋ฐ”๊ตฌ๋‹ˆ๋ฅผ Redux๋กœ!!

 

ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค๋Š” ์ด๋ ‡๋‹ค.

์œ„์—์„œ ๋ถ€ํ„ฐ ํ•˜๋‚˜ํ•˜๋‚˜ ๊ตฌํ˜„ ํ•ด๋ณด์ž!

 

์ „์ฒด์ ์œผ๋กœ๋Š” ๊ตฌํ˜„๋˜์–ด ์žˆ์—ˆ๊ณ ,

๋ถ€๋ถ„์ ์œผ๋กœ ๊ตฌํ˜„ํ•ด์•ผํ•  ๋ถ€๋ถ„์€?!

//TODO

๋ฅผ ์ฐพ์•„ ํ•ด๋ณด์ž

  1. Dispatchํ•จ์ˆ˜์— ์— ๋„˜๊ฒจ์ค„ ์ธ์ž Action์„ ์ž‘์„ฑํ•ด๋ณด์ž!
  2. Reducerํ•จ์ˆ˜์— ์ „๋‹ฌํ•  Dispatch ํ•จ์ˆ˜๋ฅผ ์ž‘์„ฑ
  3. ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค๊ฐ€ ์ž˜ ํ†ต๊ณผ๋˜์—ˆ๋‹ค๋ฉด, 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;

 

 

๊ฒฐ๊ณผ ํ™”๋ฉด!