1. 객체의 불변성을 유지해야 하는 이유
(1) JavaScript
원본 데이터가 변경이나 훼손되는 상황이 발생하지 않음을 단정할 수 있어, 예측 가능한 개발을 진행할 수 있다.
(2) React
React는 Props나 State가 변경되었을 때 리렌더링이 발생한다. 이 Props와 State의 변경을 불변성을 이용해 감지하게 된다.
(객체의 참조를 복사하는 성질을 이용해 얕은 비교를 이용해 변경 발생 여부를 확인한다)
그렇기에 React에서 모든 요소는 불변성을 지니고 있어야 한다. 특정 시점의 UI를 나타내며, UI를 업데이트하는 방법은 새 요소를 만들어 전달하는 것이 존재한다.
State는 직접 수정되어서는 안 되고, 새로운 요소로 업데이트되어야 한다.
자바스크립트에서 객체인 경우 메모리 힙 영역에 저장이 되어, 내부 프로퍼티를 변경하면 동일한 참조를 가지고 있기에 변경되었다는 사실을 인지하지 못해 리렌더링이 발생하지 않기 때문이다.
2. 객체의 불변성을 유지하는 방법
(1) JavsScript
- 얕은 복사
- Object.assign()
- Spread(스프레드) 연산자
- 깊은 복사
- JSON.parse(JSON.stringfy())
얕은 복사, 깊은 복사의 자세한 사용법은 분석기를 참고하면 된다.
(2) React
- useState
- Immer
React에선 useState를 통해 간단하게 불변성을 유지할 수 있다. useState가 setState로 값을 변경할 때 내부적으로 새로운 객체를 생성하도록 하기 때문이다.
단, 복잡한 형태의 객체에서 문제가 발생하게 된다. 새로운 요소를 만들기 위해 옮기는 과정에서 스프레드 연산자를 사용하며 직접 구현한 형태가 단순 객체로 변하는 등 성능상의 문제가 발생하게 되는 것이다.
Immer는 이러한 문제를 개선하며 불변성을 쉽게 유지하도록 돕는다. 변경할 부분의 코드만 작성하여 코드가 간결해지게 된다. Immer의 자세한 사용법은 분석기를 참고하면 된다.
3. 객체의 불변성을 명시하는 방법
(1) 종류
- Object.freeze()
- as const
(2) Object.freeze() VS as const
Object.freeze() | as const | |
에러 감지 시점 | - 컴파일 - 런타임 위의 단계에서 객체를 수정할 때 에러 감지 |
- 컴파일 위의 단계에서 타입과 다른 값 지정할 때 에러 감지 |
중첩 객체 변경 | 중첩 객체 값 변경 가능 ( 객체의 depth가 2이상인 경우 ) |
중첩 객체 값 변경 불가능 |
활용 | 런타임에 객체 속성 변경을 막고 싶을 때 활용 | 중첩 객체 속성 변경을 막고 싶을 때 활용 |
(3) 활용법
클라이언트에서 서버에게 전송하는 엔드 포인트를 모아두는 객체이다. 개발자의 실수를 줄이기 위해, 중첩 객체의 속성 변경을 막는 것이 더 목적에 부합한다고 생각하여 Object.freeze()에서 as const로 변경하여 사용하고 있다.
export const API_URL_CONFIG = {
CONTENT: {
POST_MULTIPLE: '/api/content-service',
GET: '/api/content-service',
},
} as const;
4. 언급한 분석기
JavaScript-Practice/Copy at main · minjeongss/JavaScript-Practice
레이아웃-자바스크립트 분석기 🤖. Contribute to minjeongss/JavaScript-Practice development by creating an account on GitHub.
github.com
React-Ts-Practice/Immer at main · minjeongss/React-Ts-Practice
리액트-타입스크립트 분석기 🤖. Contribute to minjeongss/React-Ts-Practice development by creating an account on GitHub.
github.com
'프로그래밍 - 활용 > Front-end' 카테고리의 다른 글
리액트의 Virtual DOM 동작 원리 분석기: Fiber Reconciler편 (0) | 2025.01.24 |
---|---|
이미지 업로드 최적화하기 (2) | 2025.01.18 |
NPM에 라이브러리 배포하기: usePortal편 (0) | 2025.01.15 |
NPM에 라이브러리 배포하기: Storybook 자동 배포편 (0) | 2025.01.14 |