No Story, No Ecstasy

리액트를 다루는 기술 개정판 [IMMER 불변성 유지] 본문

Frontend Series

리액트를 다루는 기술 개정판 [IMMER 불변성 유지]

heave_17 2021. 4. 22. 21:35

12. immer를 사용하여 더 쉽게 불변성 유지하기

  - 전개 연산자와 배열의 내장 함수를 사용하면 간단하게 객체를 복사 및 갱신이 가능하다.

  - 하지만, 객체의 구조가 엄청나게 깊어지면 불변성을 유지하면서 이를 업데이트하는 것이 힘들어진다.

  - immer를 사용하면 구조가 복잡한 객체도 매우 쉽고 짧은 코드를 사용하며 불변성을 유지하며 업데이트할 수 있다.

 

  - immer 설치

$ yarn create react-app immer-tutorial
$ cd immer-tutorial
$ yarn add immer

 

  - immer 사용법

  Ex 1)

import produce from 'immer';
const nextState = produce(originalState, draft => {
	// 바꾸고 싶은 값 바꾸기
    draft.somewhere.deep.inside = 5;
})

    . produce라는 함수는 두개의 파라미터를 받는다; (1) 수정하고 싶은 상태, (2) 상태를 어떻게 업데이트할지

    . 함수 내부에서 원하는 값을 변경하면, produce 함수가 불변성 유지를 대신해 주면서 새로운 상태를 생성한다.

    . *핵심: 불변성에 신경 쓰지 않는 것처럼 코드를 작성하되 불변성 관리는 제대로 해 주는 것

    . 배열을 처리할 때도 매우 쉽고 편하다.

  Ex 2)

import produce from 'immer';

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

const nextState = produce(originalState, draft => {
	// id가 2인 항목의 checked 값을 true로 설정
    const todo = draft.find(t => t.id ===2);
    todo.checked = true;
    
    // 배열에 새로운 데이터 추가
    draft.push({
    	id: 3,
        todo: '일정 관리 앱에 immer 적용하기',
        checked: false,
    });
    
    // id = 1인 항목을 제거하기
    draft.splice(draft.findIndex(t => t.id === 1), 1);
});

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

    . immer를 사용하면 객체 내부 값을 직접 수정하거나, 배열에 직접적인 변화를 일으키는 push, splice 등의 함수를 사용해도 무방하다.

    . 그러나, immer를 사용하면 무조건 코드가 간결해지는 것은 아니다. (onRemove의 경우, filter를 사용하는 것이 더 깔끔하다.)

      -> immer는 코드가 복잡해질 때만 사용하자.

 

    . immer와 useState를 함께 사용하기

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

const update = produce(draft => {
	draft.value = 2;
});

const originalState = {
	value: 1,
    foo: 'bar',
};

const nextState = update(originalState);
console.log(nextState); // {value: 2, foo: 'bar'}

 

    . immer는 리덕스와 함께 쓰면 매우 쉽게 코드를 작성할 수 있다.

    . 절대 필수는 아니다.