[React] React의 불변성
목차
1. 불변성이란?
2. React의 state
가 불변성을 가져야 하는 이유
3. 어떻게 하면 불변성을 가질 수 있을까?
4. state
를 직접 변경하지 않고 setState
를 써야하는 이유
1. 불변성이란?
: 값, 상태를 변경할 수 없는 것
✅ 자바스크립트의 불변성
메모리 영역의 값이 변하지 않는다 = 불변성
(1) 원시타입
let a = "data1";
a = "data2";
위 코드에서 변수 a의 값을 변경할 때, 실제로 “data1”이 있는 기존 콜스택 값은 그대로 유지된 채, “data2”를 새로운 콜스택 영역에 할당하고 그 주소로 변수 a가 바라보게 한다.
즉 메모리 영역에서 기존의 데이터가 대체되는 것이 아니라 새로운 영역을 할당하는 것으로, 원시타입은 메모리 영역의 값이 변경되지 않아 불변성을 유지한다.
(2) 참조타입
const a = [1, 2, 3];
a.push(100);
배열, 객체와 같은 참조 타입의 경우, 실제 데이터는 메모리 힙에 저장되고, 그 메모리 힙의 주소를 콜 스택의 값으로 저장된다.
즉 변수 a가 바라보고 있는 콜 스택의 값이 변경되지 않고, 메모리 힙에 있는 원본 데이터가 변경이 되기 때문에 불변성이 유지되지 않는다.
2. React의 state
가 불변성을 가져야 하는 이유
(1) 리액트의 상태 업데이트 방식
- 리액트는 화면을 업데이트할 때, 이전 상태 값과 얕은 비교를 통해 변경된 사항을 확인한 후 이뤄진다. 즉, 배열이나 객체의 속성 하나 하나를 비교하는 게 아닌, 이전 콜 스택의 주소값과 현재 주소값만을 비교하여 상태 변화를 감지한다.
✅ 얕은 비교로 하는 이유?
: 얕은 비교로 상태 업데이트를 하면, 객체의 속성을 모두 비교하는 연산이 줄어들어 효율적이다.
(2) 사이드 이펙트를 방지
- 외부의 원본데이터를 직접 수정하지 않고, 원본 데이터의 복사본을 만들어 값을 사용하게 하여 예상치 못한 오류를 방지할 수 있다.
- 즉 외부의 원본 데이터를 직접 수정하면, 원본 데이터를 이용하는 다른 곳에 사이드 이펙트가 일어날 수 있으므로 불변성을 지킴으로써 예방한다.
3. 어떻게 하면 불변성을 가질 수 있을까?
결국 참조타입의 데이터인 경우에 불변성이 유지되지 않으므로, 새로운 객체나 배열을 생성하여 상태 업데이트를 한다.
spread
,map
,filter
,slice
,reduce
등 원본 데이터를 이용해 새로운 데이터를 만들어주는 함수를 이용한다.- ✅
push
,pop
,splice
와 같은 원본 배열을 직접 수정하는 메소드는 안됨!
4. state
를 직접 변경하지 않고 setState
를 써야하는 이유
(1) 리액트의 state
는 불변성을 유지해야 한다.
- 여기서 말하는
state
는 "기존 값",setState
로 설정하는 값은 "새로 바꿀 값"으로 분리해서 생각하면 된다. 즉state
에 직접 값을 변경하면 안되고,setState
를 이용해야 불변성을 유지할 수 있다. - 이전 값과
setState
를 비교해서 업데이트가 필요한 경우에만 재렌더링이 일어난다. 만약state
를 직접 바꾸려고 하면 재렌더링이 제대로 일어나지 않는다.
(2) useEffect
- 또 직접
state
를 변경할 경우 렌더링 문제와 함께useEffect
를 통한 생명주기 제어를 할 수 없기 때문에 이러한 리액트의 핵심 기능을 사용하지 못 할 수 있다.
참고 사이트
[React] 불변성이란? 불변성을 지켜야 하는 이유
1. 개요 React를 빠르게 배울 때 값을 변경할 때 useState를 사용해야 한다, 불변성을 유지해야 한다, immer를 사용해야 한다, spread 연산자를 사용해야 한다, 공식처럼 생각하고 있었는데 javascript의 메
narup.tistory.com
OKKY - 리액트 setState 사용 이유
const [test, setTest] = useState({}); test.value = 1 console.log(test.value); 이렇게 직접 값을 넣어도value값이 넣어지는데setTest를 사용해야 하는 이유가 무엇인가요?
okky.kr