[JavaScript] Object.assign()

Tai Song·2022년 7월 6일
0

JavaScript

목록 보기
3/4
post-thumbnail
👉 오늘은 리덕트를 이용해 상태 관리를 하다가,
reducer 함수를 작성하며 객체를 합쳐야 할 필요가 있었다.
이때 Object.assign() 함수를 사용하면
간단하게 객체를 합쳐 새로운 객체로 반환할 수 있다.
let state = {
  "items": [
    {
      "id": 1,
      "name": "노른자 분리기",
      "img": "../images/egg.png",
      "price": 9900
    },
    {
      "id": 2,
      "name": "2020년 달력",
      "img": "../images/2020.jpg",
      "price": 12000
    }],
   "cartItems": [
    {
      "itemId": 1,
      "quantity": 1
    },
    {
      "itemId": 5,
      "quantity": 7
    }]
}

let newItem = {
  "itemId": 2,
  "quantity": 3
}

위와 같은 객체 데이터가 있다고 해보자.
cartItems라는 key에 newItem 객체를 추가하고 싶다면 어떻게 할까?

📌 Object.assign()으로 새로운 객체 추가

🧩 상태(state) 객체는 해당 변수에 바로 값을 할당할 수 없다는,
불변성(Immutability)을 가지고 있다는 사실을 염두에 두고
새로운 값을 추가한 새로운 객체를 만들어야 할 것이다.

const result = Object.assign({}, state, {
        cartItems: [...state.cartItems, newItem]
      })
/* newItem이 추가된 새로운 객체가 result에 담긴다 */

Object.assign()이라는 객체 메소드는 파라미터로 들어간 객체를 모두 합쳐준다.
첫 번째 파라미터 : 모든 객체가 합쳐서 모여지게 될 객체.
두 번째부터 마지막 파라미터 : 첫 번째 파라미터로 합쳐질 객체.

📌 Object.assign()으로 기존 객체 삭제

🧩 newItem을 다시 삭제하려면 어떻게 해야할까?

let removeItem = state.cartItems.filter(item => item.itemId !== newItem.itemId)
/* 삭제하고자 하는 newItem을 제외한 배열을 removeItem에 담는다 */
const result = Object.assign({}, state, {
        cartItems: [...removeItem]
      })
/* 원 배열 state에 newItem이 삭제된 배열인 removeItem을 합친다 */

📌 Object.assign()으로 기존 객체 수정

🧩 newItem의 quantity 값을 수정하려면 어떻게 할까?

      let idx = state.cartItems.findIndex(el => el.itemId === newItem.itemId)
      /* newItem의 itemId값으로 인덱스를 먼저 찾아낸다 */
      let setItem = [...state.cartItems]
      /* 새로운 배열에 전체 배열을 복사해준다 */
      setItem[idx].quantity = 1
	  /* 복사한 배열의 인덱스 값에 해당하는 배열의 수량에 수정값을 할당한다 */
      let result = Object.assign({}, state, {
        cartItems: [...setItem]
      /* 기존 객체에 수정된 배열을 Object.assign()으로 합쳐준다 */
      })

위 코드를 Redux의 reducer에 적용하기 위해서는, switch로 action.type을 받아와 각각의 case를 설정해주고 result값을 리턴하면 된다.

📌 Redux에서의 Object.assign() 사용

const itemReducer = (state = initialState, action) => {

  switch (action.type) {
    case ADD_TO_CART:
      return Object.assign({}, state, {
        cartItems: [...state.cartItems, action.payload]
      })

    case REMOVE_FROM_CART:
      let removeItem = state.cartItems.filter(item => item.itemId !== action.payload.itemId)
      return Object.assign({}, state, {
        cartItems: [...removeItem]
      })

    case SET_QUANTITY:
      let idx = state.cartItems.findIndex(el => el.itemId === action.payload.itemId)
      let setItem = [...state.cartItems]
      setItem[idx].quantity = action.payload.quantity
      return Object.assign({}, state, {
        cartItems: [...setItem]
      })

    default:
      return state;
  }
}
profile
Read The Fucking MDN

0개의 댓글