왜 리액트는 상태 객체를 복사해서 사용할까?
2019년 04월 26일리액트에서 상태를 바꿀 때 this.state.value = "b"
이런 식으로 직접 수정하지 않고 새로운 상태 객체를 만들어 사용하는 것은, 직접 수정하는 것보다 새로운 상태 객체를 만들어 쓰는게 더 이득이 크기 때문입니다.
리액트 공식 페이지에서는 아래 3가지 이유를 들고 있습니다.
1. 복잡한 기능을 쉽게 구현할 수 있습니다.
메모장이나 워드 같은 프로그램을 보면 되돌리기(undo), 다시하기(redo) 같은 기능을 지원합니다. 이런 기능을 구현하기 위해서는 무엇이 필요할까요? 과거 데이터의 상태 변화를 계속해서 추적 관리해야 하는데 이게 쉬운 일이 아닙니다. 그런데 이렇게 매 동작마다 새로운 상태를 만들어(복사해서 필요한 부분만 수정 후 setState 호출) 사용하면 언제든지 과거의 특정 시점으로 돌아 갈 수 있도록 만드는 일을 정말 쉽게 구현할 수 있습니다.
2. 변화된 부분을 찾아내기 쉽습니다.
상태 객체를 직접 수정해버리면 뭐가 어떻게 변화되었는지 찾아내기가 정말 어렵습니다. 이전 상태와 뭐가 다른지 일일이 비교해야 하고 전체 상태 객체의 트리를 타고 내려가며 탐색해야 합니다. 이 과정을 매 상태 변화가 일어났던 수 십번의 과정을 모두 수행한다고 생각하면 끔찍한 일이지요. 상태 객체를 복사해서 새로운 상태를 통채로 만들어 쓰면(이걸 불변성이라고 합니다.) 변화된 부분을 찾아내는 것은 누워서 떡 먹기입니다.
3. 랜더링이 필요한 시점을 판단하기 쉽습니다.
상태 객체의 불변성을 유지하는 가장 큰 이유는 리액트에서 순수 컴포넌트(Pure Component)를 만드는데 도움을 주기 위함입니다. 아래 두 가지 조건을 충족하면 순수 컴포넌트라고 볼 수 있습니다.
- 오직 입력 값에 의해서만 리턴 값이 결정됩니다.
- 같은 입력 값이 들어가면 항상 같은 값이 리턴됩니다.
어떤 컴포넌트가 같은 state와 props에 대해 같은 결과물을 랜더링한다면 리액트는 그 컴포넌트를 ‘순수 컴포넌트(Pure Component)’라고 봅니다. 객체의 불변성 유지는 “같은 state와 props” 라는, 순수 컴포넌트가 되기 위한 조건을 판단하고 충족시키는데 큰 도움이 도움을 줍니다.