[React JS] 리액트를 다루는 기술 - immer를 사용하여 더 쉽게 불변성 유지하기

 

1. 불변성이란?

'불변성을 지킨다'는 것은 기존의 값을 직접 수정하지 않으면서 새로운 값을 만들어내는 것을 말한다.

리액트 컴포넌트에서 상태를 업데이트할 때 불변성을 지키는 것은 중요하다.

 

 

 

2. immer 라이브러리 사용 이유

전개 연산자와 배열의 내장 함수를 사용하면 간단하게 배열 혹은 객체를 복사하고 새로운 값을 덮어 쓸 수 있다.

하지만, 객체 안에 배열 안에 객체...처럼 중첩된 배열이나 객체가 많아 객체의 구조가 많이 깊어지면 불변성을 유지하며 업데이트하는 것은 힘들다.

 

이때, immer 라이브러리를 사용하면, 구조가 복잡한 객체도 쉽고 짧은 코드로 불변성을 유지하면서 업데이트할 수 있다.

 

 

 

 

3. immer 설치 및 사용법

 

< immer 설치 >

리액트 프로젝트를 생성한 후 터미널 창에 npm 혹은 yarn을 이용해 다음 명령어를 넣어준다

npm install immer
yarn add immer

 

< immer 사용법 >

▶ immer를 import 해오기

import produce from 'immer';

 

▶ immer 사용

const nextState = produce(originalState, draft => {
  // 바꾸고 싶은 값 변경
  draft.somewhere.deep.inside = 5;
})

produce라는 함수는 두 가지 파라미터를 받는다.

  • 첫 번째 파라미터: 수정하고 싶은 상태
  • 두 번째 파라미터: 상태를 어떻게 업데이트할 지 정의하는 함수

두 번째 파라미터로 전달되는 함수 내부에서 원하는 값을 변경하면, produce 함수가 불변성 유지를 대신 해주며 새로운 상태를 생성해준다.

 

 

< immer 사용 했을 때와 안했을때 차이 >

 

▶ immer 사용하지 않고 불변성 유지한 경우

const onRemove = useCallback(
  id => {
    setData({
      ...data,
      array: data.array.filter( info => info.id !== id)
    })
  }
  , [data]
);

 

▶ immer 사용한 경우

setData(
  produce(draft => {
    draft.array.push(indo);
  })
);

 

immer 라이브러리는 불변성에 신경을 쓰지 않는 것처럼 코드를 작성하지만 불변성 관리는 제대로 해준다.

 

 

▶ immer를 사용하여 복잡한 데이터의 불변성을 유지하면서 업데이트하는 예시

import produce from 'immer';

const originalState = [
  {
    id: 1,
    todo: '전개 연산자와 배열 내장 함수로 불변성 유지',
    checked: true,
  },
  {
    id: 2,
    todo: 'immer'로 불변성 유지',
    checked: false,
  },
];

const nextState = produce(originalState, draft => {
  const todo = draft.find( t => t.id === 2 );
  todo.checked = true;
  
  draft.push({
    id: 3,
    todo: '일정 관리 앱에 immer 적용',
    checked: false,
  });
  
  draft.splice(draft.findIndex( t => t.id === 1), 1);
});

 

immer를 사용하여 컴포넌트 상태를 객체 안에 있는 값을 직접 수정하거나, 배열에 직접적인 변화를 일으키는 push, splice 등의 함수를 사용해도 무방하다.

 

※ immer는 불변성을 유지하는 코드가 복잡할 때만 사용해도 충분하다.

 

 

 

4. useState의 함수형 업데이트와 immer 함께 쓰기

immer에서 제공하는 produce 함수를 호출할 때, 첫 번째 파라미터가 함수 형태이면 업데이트 함수를 반환한다.

 

immer의 속성과 useState의 함수형 업데이트를 함께 사용하면 더 깔끔한 코드 작성이 가능하다.

 

 

반응형