티스토리 뷰
🔎 불변성 ?
사전적으로 불변성이란 값이나 상태를 변경할 수 없는 것을 의미합니다.
이 의미를 정확하게 이해하기 위해 자바스크립트의 원시타입에 대해 먼저 알아보도록 합시다.
❓ 원시타입 vs 참조타입
자바스크립트에서 원시타입에는 Number, Strimg, Boolean, null, undefined, Symbol
참조타입에는 Object, Array가 있습니다.
이때 원시타입은 고정된 크기로 메모리에 저장, 실제 데이터가 변수에 할당되며
참조타입은 데이터 크기가 정해지지 않고 메모리에 저장, 데이터의 값이 heap에 저장되며 변수에 heap 메모리의 주소값이 할당됩니다.
즉, 원시타입들은 불변성을 유지하고, 참조타입들은 변경이 가능한 값들이라는 말입니다.
원시타입은 불변성을 유지한다
let string= 'data1';
string = 'data2';
변수 string은 data1 → data2로 값이 변경되었습니다.
위 예시를 보면 string 변수는 'data1' → 'data2'로 값이 변경된 것처럼 보입니다.
하지만 실제 메모리 영역에는 'data1', 'data2' 둘다 존재합니다.
let string = 'data1'; // 1. string: 'data1'가 메모리 영역1에 등록
string = 'data2'; // 2. string: 'data2'가 메모레 영역2에 등록
즉, 위 예시에서 메모리 영역을 총 2개 사용한 것이 됩니다.
변수 string은 'data1'이었고, 여기에 'data2'를 재할당하였는데 기존 메모리 영역 1에 있는 'data1'의 값은 그대로 두고, 메모리 영역2에 'data2'를 새로 할당하였습니다.
즉, 메모리 영역에서 'data2'는 'data1'을 대체하는 것이 아니라 새로운 영역에 할당됩니다.
다른 원시타입들도 마찬가지이고, 이것을 불변성이라고 합니다.
참조타입의 불변성을 지켜야 한다
let array = [1, 2, 3, 4]; // 메모리 영역1
array.push(5); // 메모리 영역 1
array = [1, 2, 3, 4]; // 메모리 영역2 (새로운 참조값)
array.push(5)는 원본 데이터를 수정함으로써 불변성을 지켜주지 않은 것이 되고,
array = [1, 2, 3, 4]는 새로운 배열 [1, 2, 3, 4]을 할당하고 새로운 참조값을 만들어주어 불변성을 지켜준 것이 됩니다.
var coke = {
name: 'coca',
price: 2000,
};
var new_coke = coke;
coke.name = 'pepsi';
console.log(coke.name, new_coke.name); // 'pepsi' 'pepsi'
위 예제에서는 new_coke와 coke가 대입 연산자를 통해 얕은 복사가 되었습니다.
따라서 같은 메모리 주소를 공유하고 있습니다.
new_coke만 수정한 것 같아 보여도 동일한 메모리 주소를 공유하고 있어 같이 값이 변경되었으며 불변성이 지켜지지 않은 예시가 됩니다.
💡💡 React에서 state의 불변성
이제 React에서 state의 불변성을 지키는 이유에 대해 알아봅시다.
결론부터 이야기 하지면, 리액트에서 state를 업데이트하는 원리 때문입니다.
리액트는 상태값을 업데이트할 때 얕은 비교를 수행합니다.
즉, 객체의 속성 하나하나를 비교하는 게 아니라 참조값만 비교하여 상태 변화를 감지합니다.
→ state의 메모리 주소가 바뀌었으면 리렌더링
따라서 Object나 Array의 속성이나 값을 바꾸는
불변성이 지켜지지 않은 state는 React에서 감지하지 못하기 때문에
이러한 경우에는 불변성을 지키는 업데이트가 필요한 것입니다.
그러므로 배열이나 객체의 경우에는
깊은 복사를 통해 새로운 참조값을 만들어서 상태를 업데이트 해야만 합니다.
이렇게 불변성을 지켜줌으로써 또 다른 이점은 바로 사이드 이펙트를 방지한다는 점인데요.
즉 외부에 존재하는 원본 데이터를 직접 수정하지 않고, 원본 데이터의 깊은 복사본을 만들어서 값을 사용하기에
예상치 못한 오류를 사전에 방지할 수 있습니다.
state는 하나의 컴포넌트가 참조하는 것이 아니라 굉장히 많은 텀포넌트가 참조할 수 있습니다.
그러나 외부에서 원본 데이터를 사용하고 있을 때 외부에서 state의 값이 수정되면 해당 상태를 참조하고 있는 다른 컴포넌트들에서 예상치 못하는 에러가 발생할 수 있습니다.
정리! 리액트에서 불변성을 지켜야하는 이유
1. 효율적인 상태(state) 업데이트
얕은 비교란 객체의 프로퍼티를 하나하나 다 비교하지 않고, 객체의 메모리 주소값만 변경되었는지 확인합니다.
얕은 비교는 객체의 속성값을 일일이 확인하지 않아도 참조값만을 비교하여 상태를 업데이트하기 때문에
계산 리소스를 줄여주어 효율적입니다.
따라서 Object나 Array 타입의 경우 불변성을 지킴으로써 효율적인 상태 업데이트가 가능해 집니다.
2. 사이드 이펙트 방지
원본 데이터가 변경될 경우, 이 원본 데이터를 같이 참조하고 있는 다른 객체에서 예상치 못한 에러가 발생할 수 있습니다.
따라서 깊은 복사를 통해 불변성을 지킴으로써 서로 다른 참조값의 state를 관리하도록 해 사이드 이펙트를 방지할 수 있습니다.
'프론트엔드 > React' 카테고리의 다른 글
[React] useContext로 전역 상태 관리를 하자 (0) | 2023.02.20 |
---|---|
[React] useReducer로 상태 업데이트 로직을 분리하자 (0) | 2023.02.20 |
[React] 커스텀 Hooks - 중복되는 로직을 한줄로 처리하도록 (0) | 2023.02.13 |
[React] useCallback - 함수를 재사용하자 (0) | 2023.02.13 |
[React] useMemo - 연산한 값을 재사용하자 (0) | 2023.02.13 |
- Total
- Today
- Yesterday
- react-query
- frontend
- rtl
- testing
- Python
- 프론트엔드 기초
- TypeScript
- 프론트엔드 공부
- HTML
- 디프만
- react
- JSP
- 리액트
- next.js
- CSS
- 스타일 컴포넌트 styled-components
- 프론트엔드
- 자바
- 데이터분석
- 딥러닝
- 머신러닝
- 파이썬
- 인프런
- 리액트 훅
- 자바스크립트
- 자바스크립트 기초
- styled-components
- 타입스크립트
- jest
- 프로젝트 회고
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |