혼자 적어보는 노트

[React] immer를 사용한 불변성 관리 본문

React

[React] immer를 사용한 불변성 관리

jinist 2021. 12. 9. 17:29

데이터 관리를 하다보면 2차원, 3차원 등등의 깊은 객체들을 다룰 일들이 생긴다.

state의 불변성을 지키기 위해 코드를 짜다보면 깊은 객체에 데이터 하나를 수정하는데에

길고 복잡한 코드를 작성해야 한다.

 

아래는 직접 난항을 겪은 예시 데이터이다

 

const addCart = [
  {
    id: 1,
    name: "모자",
    description: "털모자",
    price: 27000,
    option: [
      { optionName: "blue", quan: 1 },
      { optionName: "black", quan: 1 },
    ],
  },
  {
    id: 2,
    name: "자켓",
    description: "겨울자켓",
    price: 27000,
    option: [{ optionName: "blue", quan: 1 }],
  },
];

예를들어 이러한 데이터가 있다고 가정해보고

id가 1인 상품에 option의 optionName이 "blue"인 상품의 quan을 +1 해보는 코드를 작성해보자.

 

 

console.log(
  [...addCart].map((product) =>
    product.id == 1
      ? {
          ...product,
          option: product.option.map((option) =>
            option.optionName === "blue"
              ? {
                  ...option,
                  quan: option.quan + 1,
                }
              : option
          ),
        }
      : product
  )
);

너무나도 길고 복잡해보인다.

 

 

immur사용

import produce from "immer";

const nextState = produce(addCart, (draft) => {
  const product = draft.find((item) => item.id === 1);
  const foundOption = product.option.find(
    (option) => option.optionName === "blue"
  );
  foundOption.quan++;
});

console.log(nextState);

위와같이 immer사용으로 코드를 간단하게 줄일 수 있다.

 

물론 immer을 사용하지 않은 코드가 성능면에서는 빠르고

깊지 않은 객체를 다룰 땐 직접 짜는 코드가 더 간단하기도 하다.

 

잘 선택해서 사용하자

 

 

 

++

Redux reducer에서 immer 사용

const reducer = (state = initialState, action) => {
  return produce(state, (draft) => {
    switch (action.type) {
      case ADD_COMMENT:
        const post = draft.mainPosts.find((item) => item.id === action.data.postId);
        post.Comments.unshift(dummyComment(action.data.content));
        break;
      default:
        break;
    }
  });
};

위와 같이 produce로 switch문을 감싸고 break을 사용하여

불변성 걱정 없이 state변경이 가능하다.

Comments