[React] 불변성이란? 불변성을 지켜야 하는 이유

수민🐣·2022년 12월 21일
0

React

목록 보기
22/36

javascript 메모리 구조


자바스크립트 엔진은 call stackheap memory 2가지 메모리 공간을 가지고 있다.

  • call stack
    실행 중인 함수를 추적해 계산을 수행하고 지역변수를 저장하는 공간
    원시 타입들이 저장
  • heap memory
    참조 타입들이 할당 되는 곳

원시타입과 참조 타입의 데이터 저장방식

  • 원시타입
    변수 a에 값 10을 저장할 경우, 콜 스택의 변수 값에 10 그대로 저장
  • 참조타입
    변수 b,c,d에 array object를 저장할 경우, 실제 값은 메모리 힙에 저장되고 메모리 힙의 주소가 콜스택 값에 저장된다.

원시타입과 참조 타입의 재할당

원시 타입의 특징


원시타입의 변수는 변수값을 변경하라는 명령을 받을 경우, 기존 콜스택의 값을 변경하지 않고 새로운 주소를 추가해 값을 저장하고 변수 b가 바라보게 한. 이것을 불변성이라고 한다.

참조 타입의 특징


a.에서 변수값을 할당하고, b.에서 push를 통해 값을 추가하게 되면 실제로는 변수 a,b가 바라보고 있는 콜스택의 값이 변경되지 않고, 메모리 힙에 있는 데이터가 변경이 되어 불변성이 유지가 되지 않는다!

리액트에서 불변성을 지켜야 하는 이유

리액트의 state 변화 감지 기준은 콜 스택의 주소값이기 때문이다. 이를 얕은 비교라고 한다.

원시타입의 경우 값을 재할당때 새로운 메모리가 할당되어 콜 스택의 주소 값이 감지가 됩니다.
하지만 참조타입의 경우 참조타입의 값만 변경하면 실제로 콜스택의 주소값은 변경이 없어 state 감지가 되지 않아 리렌더링이 되지가 않는다. 그래서 spread 연산자를 쓰고, immer 라이브러리를 사용해 새로운 배열과 오브젝트를 만들어 반환하는 이유

얕은 복사(shallow copy)

객체를 직접 대입하는 경우 참조에 의한 할당이 이루어지므로 둘은 같은 데이터(주소)를 가지고 있다.

const obj1 = { a: 1, b: 2};
const obj2 = obj1;
console.log( obj1 === obj2 ); // true

깊은 복사(deep copy)

아예 새로운 객체안 속성(property)만 복사 해서 사용할 수 있다.
방법 1. …(spread) 연산자를 통한 복사

const obj1 = { a:1, b:2 };
const obj2 = { ...obj };
obj2.a = 100;
console.log( obj1 === obj2 ) // false
console.log( obj1.a ) // 1

방법 2. Object.assign() 메소드를 통한 복사

const obj1 = { a:1, b:2 };
const obj2 = Object.assign({}, obj1);
obj2.a = 100;
console.log( obj1 === obj2 ) // false
console.log( obj1.a ) // 1

0개의 댓글