기존에 내가 작성한 immer 예제는 너무 간단해서 오히려 immer를 왜 쓰는지 이해하기 힘든 느낌이 들어서 공식문서 예제를 읽어봤다.
const baseState = [
{
title: "Learn TypeScript",
done: true
},
{
title: "Try Immer",
done: false
}
]
위와 같은 기본 상태가 있다고 가정한다.
두 번째 업데이트하고 세 번째 할 일을 추가해야 합니다. 그러나 원래 기본 상태를 변형하고 싶지 않으며, (첫 번째 할 일을 보존하기 위해) 심층 복제도 피하고 싶습니다.
// baseState 배열을 slice()를 사용해 배열을 얕은 복제하고, nextState라는 새 배열에 저장
const nextState = baseState.slice()
// nextState[1]은 nextState 배열의 두 번째 요소
nextState[1] = {
// nextState[1]을 새로운 객체로 교체
...nextState[1], // ...nextState[1]을 사용해 nextState[1] 요소를 얕은 복사하여 새로운 객체를
done: true // done 속성을 true로 업데이트
}
// 수정할 두 번째 요소를 바꾼 뒤 다시 배열에 push함
// nextState 배열의 끝에 새로운 항목 { title: "Tweet about it" } 데이터를 추가했다는 말
nextState.push({title: "Tweet about it"})
- 첫 번째 인수 ⇒ 수정하고 싶은 상태
- 두번째 인수 ⇒ 상태를 어떻게 업데이트할지 정의하는 함수를 전달
두 번째 파라미터로 전달되는 함수 내부에서 원하는 값을 변경하면 produce 함수가 불변성 유지를 대신해 주고, 새로운 상태를 생성해 줌!
import {produce} from "immer"
// baseState = 원본 상태 배열 , draft = baseState의 가벼운 복사본
const nextState = produce(baseState, draft => {
// produce 함수는 draft를 수정한 후 새로운 상태를 반환하는데,
// 이때, draft에서의 변경 사항만 반영된 새로운 상태가 만들어짐!
draft[1].done = true // draft에서 두 번째 항목의 done을 true로 설정
draft.push({title: "Tweet about it"}) // draft에 새 항목 추가
})