ABOUT ME

-

Today
-
Total
-
  • Immer 라이브러리로 쉽게 React state 불변성 지키기
    Study/React 2020. 1. 12. 11:37
    반응형

     

    https://immerjs.github.io/immer/docs/introduction

     

    기존에 Immer 라이브러리를 사용하지 않고 불변성을 지켜주기 위해서는

    spread 연산자를 통해 기존 객체를 복사하거나, 내장 함수를 사용하여 불변성을 지켜 업데이트를 해줬다.

    하지만 데이터 구조가 복잡해질수록 위와 같은 방법을 사용하면 코드가 복잡해질 것이다.

     

    그러나 Immer 라이브러리를 사용하면 쉽게 불변성을 지켜줄 수 있다.

    Immer를 사용하면 상태를 업데이트 할 때 불변성을 신경 쓰지 않아도 Immer가 알아서 불변성을 관리해준다.

    즉, 배열의 원본을 바꾸는 push, splice 등의 메소드도 사용할 수 있다는 것이다.

     

    Immer 라이브러리는 데이터의 구조가 복잡해서 불변성을 유지하며 업데이트 할 코드가 복잡해 질 때 사용하는게 좋다.

     

    Immer 사용법

     

    import produce from "immer"

     

    - 작업할 디렉토리에서 immer 설치 :  yarn add immer

    - App 컴포넌트 상단에서 produce 함수를 불러온다.

     

    const nextState = produce(currentState, draft => { function })

     

    - nextState : 다음 상태 변수 이름

    - currentState : 업데이트하고자 하는 현재 상태값

    - draft : 현재 상태값을 복사하여 사용

    ( 상태를 바꾸는 함수는 draft에 적용되어 새로운 상태를 리턴한다 )

    - function : 어떻게 업데이트하고 싶을지 정의하는 함수

     

    const state = {
      number: 1,
      text: 'immutable'
      };
      
    const changeState = produce(state, draft => {
    	draft.number += 1;
      };
      
    
    /*console.log(changeState);
    {
      number: 2,
      text: 'immutable'
    };
     */


    const changeState = produce(state, draft => {
    draft.number += 1;
      };

     

    : draft는 변수 state에 해당하기 때문에 number를 바꿀 때 draft에 적용하면 된다.

    changeState는 number가 2로 바뀐 객체를 리턴한다.

     

     

     

    useState 함수형 업데이트에 Immer 사용하기

     

    const [todo, setTodo] = useState({
      text: 'Study',
      done: false
    });
    
    const onClick = useCallback(() => {
      setTodo(todo => ({
        ...todo,
        done: !todo.done
      }));
    }, []);

    useState를 사용할 때 setTodo 함수에서 함수형 업데이트를 해줘야만 deps에 todo를 넣지 않아도 되게 된다.

     

    Immer에 첫 번째 파라미터인 상태값을 생략하고, 두 번째 파라미터인 업데이트 함수만 넣어주게 된다면

    produce 함수가 반환하는 것은 상태를 업데이트 해주는 함수가 된다.

    따라서 함수형 업데이트 자리에 produce 함수를 넣어주면 쉽게 불변성을 유지할 수 있다.

     

    const [todo, setTodo] = useState({
      text: 'Hello',
      done: false
    });
    
    const onClick = useCallback(() => {
      setTodo(
        produce(draft => {
          draft.done = !draft.done;
        })
      );
    }, []);

     

    위처럼 todo를 spread 연산자로 복사하지 않고도, produce 함수로 불변성을 유지한 채 상태를 업데이트 할 수 있다.

     

     

     

    반응형

    댓글