[React] 불변성과 Immer

조수현·2025년 10월 19일

서론

수업 복습하던 중,,, 배웠는데 집중 못 해서 넘어갔던 개념을 발견해 적어본다

참고

불변성이란

상태를 변경할 수 없음을 의미합니다

  • 이렇게만 보면 와닿지 않아 예시와 함께 보자
let message = 'hello'
let temp = message
message = 'world'

console.log(message) // world
console.log(temp) // hello
  • message라는 변수의 값이 hello에서 world로 변경된 것 처럼 보인다.
  • temp는 message라는 변수를 참조하고 있지만 message를 변경해도 temp의 값은 변하지 않고 hello로 유지된다
  • 여기서 message값의 변경이 temp값에도 변경을 준다면 불변성이 지켜지지 않았다고 한다.
let array = [1, 2, 3]
let tempArray1 = array
let tempArray2 = [...array]

array[0] = 100

console.log(tempArray1) // 1?
console.log(tempArray2) // 2?
  • 배열에서는 전개 연산자를 사용하여 배열 복사해야 불변성이 지켜진다
  • 1번은 전개 연산자를 사용하지 않은 경우고 2번은 전개 연산자를 사용하여 배열을 복사하였다
  • array를 수정했을 때 1번은 array의 수정사항이 반영되어 출력되고 2번은 반영되지 않고 불변성이 유지 되었다

immer란

react에서 중요한 불변성의 쉬운 관리를 돕는 라이브러리

  • 위에서 확인한 배열의 불변성과 객체는 동일한 방법으로 불변성을 유지한다
  • 다만 깊은 복사(전개 연산자 사용)에도 한계가 있어 더욱 쉽게 관리하기 위해 나온 라이브러리가 immer다

draft state

  • 다음 상태로 변경되기 전 현재 상태에서 변경 사항을 적용하는 프록시 상태이다
  • draftState를 기반으로 nextState를 변경한다
  • 아래 produce와 함께 설명함

produce

immer에서 사용하는 상태 변경 함수

기본 구조

produce(baseState, recipe: (draftState) => void): nextState
  • 변경하고다하는 상태를 baseState에 넣는다
  • baseState에서 변경하고자 하는 데이터를 넣는다
  • 변경하는 방법을 recipe에 넣는다
  • 반환 값으로 다음 상태값을 받는다

적용


const baseState = [
    {name: 'podo', age: 5},
  {name: 'yuza', age: 2},
  {name: 'bambi', age: 1}
]

const nextState = produce(baseState (draftState) => {
	draftState.push({name: 'soohyun', age: 18})
  	draftState[2].age = 3
})

console.log(baseState)
console.log(nextState)
  • 객체 복사의 과정을 개발자가 할 필요 없이 baseState에 영향을 주지 않은 채로 값의 수정이 가능하다
  • 직관적으로 객체 데이터 값의 수정이 가능하다

useImmer

  • useState대신 바로 immer를 사용할 수 있는 훅이다
const [todos, setTodos] = useImmer(initialState); 

const handleDone =()=>{
	setTodos(draft=>{
    	draft[0].done = true;
    })
}
  • 기존 useState와 동일하지만 set함수의 콜백으로 들어가는 함수가 produce의 recipe와 동일하다
  • draft개념을 사용하기 때문에 직관적으로 값의 변경이 가능하다
  • 객체 상태 관리 시 유용하게 사용이 가능하다

마무리

캡슐화의 장점은 내가 내부동작을 모르고 간편하게 사용이 가능 하지만 단점은 내부 동작을 모르고 사용하는 게 어떤 부작용을 줄 지 모르겠어서 무섭다 ㅠ 아직 나의 프로젝트에 immer를 적용하지는 않았지만 부트캠프 수업에서도 사용할 정도로 안정적이라니 좀 더 사용을 고려해 봐야겠다 ㅋㅋㅋ ㅠㅠ

profile
프론트엔드 개발 블로그

0개의 댓글