React immer를 활용한 손쉬운 불변객체 다루기

에듀캐스트 장고&리액트 강의를 듣고 정리하는 글이다.

불변성 (Immutable)

리액트에서는 불변성을 유지하면서, 상탯값을 업데이트해야만 한다.

object는 다음과 같이 처리하여 불변성을 유지할 수 있다.

const todo ={
  name: 'immer 이해하기'
  is_compelted: false,
};

const newState = {
  ...todo,
  is_compelted: true
}

하지만 배열의 경우에서는 유지하기가 힘들다.

const fruits = ["orange", "apple", "lemon", "banana"]

// 제거된 객체들을 반환하며, fruits 객체를 변경한다.
fruits.splie(1, 2, "strawberry")


// 아래처럼 하면 fruits의 불변성을 유지할 수 있지만, 가독성이나 관리가 쉽지 않다.
const newFruites = [
  ...fruits.slice(0, 1),
  "strawberry",
  ...fruits.slice(3),
]

// immer를 사용하면, 익숙한 코드로 불변성을 지킬 수 있다.
const newFruites = produce(fruits, draft => {
  draft.splice(1, 2, "strawberry");
})

immer 설치

yar add immer

// node.js

const { produce } = require('immer');

// const fruits = ['오렌지', '사과', '레몬', '바나나'];

// const newFruits = produce(fruits, (draft) => {
//   draft.splice(1, 2, '딸기');
// });

// console.log(newFruits);

const baseState = [
  {
    todo: 'Learn ES6+',
    done: true,
  },
  {
    todo: 'Try immer',
    done: false,
  },
];

// const newbaseState = [...baseState, { todo: 'Tweet about it' }];
// newbaseState[1].done = true;

const newbaseState = [
  ...baseState.map((tweet, index) =>
    index === 1 ? { ...tweet, done: true } : tweet,
  ),
  { todo: 'Tweet about it' },
];

const newimmerState = produce(baseState, (draft) => {
  draft[1].done = true;
  draft.push({ todo: 'Tweet about it' });
});

console.log(baseState);
console.log(newbaseState);
console.log(newimmerState);