본문 바로가기

Frontend Study - 2/React

React : Immer 사용하기

주로 리액트 상태관리에서 useState,

전역관리에는 context API, Redux를 사용했었는데 상태와 관련한 그 밖에 다른 라이브러리들이 있었다.

 

중첩되어 있어서 복잡한 형태라면 useReducer를 통해 별도 함수를 만들어 관리 할 수 있었고,

(분리되어 있기 때문에 재사용 가능하고, 테스트하기에도 편하다)

 

이번에 공부하게 된 Immer 라이브러리는 상태변경과 관련된 라이브러리이다.

중첩된 객체 데이터의 변경에서 보다 더 편하게 사용할 수 있었다. 기존의 방법보다 훨씬 직관적으로 변경할 수 있게 된다. 

 

기존 리액트에서는 상태를 변경할 때 기존 상태값을 직접적으로 바꾸는 것이 아니라 불변성을 지키며 상태를 변경시킨다. 

보통 spread 연산자를 사용하여 기존데이터의 복사본을 만든 뒤에 그 복사본을 수정하는 식으로 변경한다. 

 

Immer에서는 직접 수정하는 것처럼, 마치 일반 오브젝트를 업데이트 하는 것처럼 데이터를 수정할 수 있게 된다.

하지만 실제로 직접 수정하는 것은 아니다.  Immer내부에서 useState를 사용하여 새로운 객체를 만들어서 원하는 부분을 업데이트 해주는 방식이다.

 

 

 

 

설치

yarn add immer use-immer

 

사용법

import {useImmer} from 'use-immmer'


export default function AppMentorsImmer() {
	const [person, updatePerson] = useImmer(initialPerson);
	updatePerson(person => person.name = '변경하는 이름');
 ...

 

useImmer로 만든 updatePerson을 이용해서 기존 값에 쉽게 접근할 수 있게 된다. 

 

예시2)

updatePerson((person) => {
	const mentor = person.mentors.find(m=>m.name === '입력한이름');
	mentor.name = current;
    })

 

 

공식문서 예시1)

const nextState = baseState.slice() // shallow clone the array
nextState[1] = {
    // replace element 1...
    ...nextState[1], // with a shallow clone of element 1
    done: true // ...combined with the desired update
}
// since nextState was freshly cloned, using push is safe here,
// but doing the same thing at any arbitrary time in the future would
// violate the immutability principles and introduce a bug!
nextState.push({title: "Tweet about it"})

위의코드가 아래처럼 바뀌게 된다.

import produce from "immer"

const nextState = produce(baseState, draft => {
    draft[1].done = true
    draft.push({title: "Tweet about it"})
})

 

 

공식문서 예시2)

 function updateName(name) {
    updatePerson(draft => {
      draft.name = name;
    });
  }

  function becomeOlder() {
    updatePerson(draft => {
      draft.age++;
    });
  }

 

 

 

참고사이트

https://github.com/immerjs/immer