오랜만에, deep dive 교재를 다시 읽다가 단순히 규칙처럼 사용했던 불변성에 대해서 왜 그랬을까? 라는 고민을 하게 되었고 작성하게 되었습니다.
자바스크립트 객체의 특징
우선 객체에 대해서 먼저 알 필요가 있습니다.
JS에서 객체는 JAVA나 C++와 같은 클래스 기반 객체지향 언어와 다르게, 동적으로 프로퍼티를 삭제 및 추가할 수 있다.
그렇기 때문에 객체의 경우에 정확히 얼마만큼의 메모리 공간을 확보해야 할지 정할 수 없습니다.
또한 원시값들을 처리하는 것 처럼 객체가 수정될 때마다 새로운 메모리공간에 수정된 객체를 추가하는 작업은 메모리의 효율이 떨어지고 성능을 저하시킨다.
따라서 자바스크립트에서는 해당 객체의 직접적인 주소를 변수에 할당하는 것이 아니라, 해당 객체가 위치하는 메모리 주소를 할당한다. 이를 원시값에서 주소를 직접적으로 할당하는 것과 구별짓기 위해서 교재에서는 ' 공유 에 의한 전달'(참조에 의한 전달)이 라고 한다.
(공유에 의한 전달이 좀 더 정확한 표현이라 느끼나 참조에 의한 전달이 보편적으로 사용되는 느낌입니다.)
즉, 동적인 객체를 효율적으로 관리하기 위해서 위와 같은 공유에 의한 전달 방법을 사용하지만, 그러다 보니 여러 객체가 동일한 하나의 객체를 공유하는 문제도 발생하게 된다. 하지만 객체를 하나하나 프토퍼티 값까지 확인하는 것이 아니라 주소 값을 확인하기 때문에 효율적으로 관리할 수 있게 된다.
리액트에서 불변성이 중요한 이유
리액트도 결국 자바스크립트 기반의 라이브러리입니다. 리액트에서는 업데이트 전 후의 두 가지의 가상 돔을 diffing 알고리즘으로 비교하여 변경된 부분만 리렌더링합니다. 따라서 변화를 감지하기 위해서 불변 객체를 사용하여 참조(공유)하고 있는 값이 다르다면 객체가 변했다고 인지하도록 합니다.
이때 원시값들처럼 객체를 변경할 때 객체 자체를 변경하는 것이 아니라 참조(공유)되고 있는 주소 값이 다르게 하는 것을 불변성을 지킨다고 합니다.
React will ignore your update if the next state is equal to the previous state, as determined by an Object.is comparison. This usually happens when you change an object or an array in state directly:
// 출처 : https://react.dev/reference/react/useState
그리고 불변성을 지키기 위해선 spread문법을 활용하여 새로운 객체를 만드는 것을 공식문서에서는 추천합니다.
setObj({
...obj,
x: 10
});
참고문헌
자바스크립트 deepdive 교재
https://react.dev/reference/react/useState
useState – React
The library for web and native user interfaces
react.dev
https://legacy.reactjs.org/docs/reconciliation.html?
Reconciliation – React
A JavaScript library for building user interfaces
legacy.reactjs.org
'프론트엔드 > React' 카테고리의 다른 글
WebRTC 기술 구현하기 (0) | 2024.12.11 |
---|---|
간소화된 SPA 구현하기 (0) | 2024.11.17 |
URL 기반 검색 기능 만들기 (URLSearchParams, Router) (1) | 2024.10.26 |
Intersection Observer API를 활용하여 무한 스크롤 구현하기 (0) | 2024.10.07 |
input 요소 uncontrolled와 controlled 관련 Warning (0) | 2024.05.01 |