Immutability (불변성)
🧩 Related
불변성이란 데이터를 직접 변경하지 않고, 항상 새로운 값으로 갱신하는 프로그래밍 원칙을 말한다.
구분 | 설명 |
---|---|
불변(Immutable) | 한 번 만들어진 값은 절대 변경되지 않음. 변경하려면 새로운 값을 만들어야 함. |
가변(Mutable) | 기존 값을 직접 수정할 수 있음. 메모리 주소가 유지됨. |
원시형(Primitive) | 기본적으로 불변 — 값을 변경하면 새 값이 생성됨. |
참조형(Reference) | 기본적으로 가변 — 내부 속성을 바꾸면 같은 주소에서 값이 바뀜. |
js
// 원시형 (불변)
let a = 10;
let b = a;
b = 20;
console.log(a); // 10 (a는 변하지 않음)
// 참조형 (가변)
const obj1 = { name: 'Binny' };
const obj2 = obj1;
obj2.name = 'Milou';
console.log(obj1.name); // "Milou" (같은 객체를 참조)
💡 왜 불변성이 중요할까?
불변성은 상태 관리와 렌더링 효율의 핵심 원리다.
React 렌더링 감지 방식
: React는 객체의 참조가 달라졌는지를 비교하여 상태 변경 여부를 판단한다.직접 변경 시 문제
: 같은 객체를 수정하면 참조가 바뀌지 않아 React가 변경 없음으로 판단 → 렌더링이 일어나지 않음.새 객체 생성의 효과
: 새로운 객체를 반환하면 참조가 변경되어 React가 변경됨으로 감지함.
jsx
// 잘못된 예시 (기존 상태 직접 수정)
state.user.name = 'Binny';
setState(state); // 참조 동일 → React는 변화 감지 못함
// 올바른 예시 (새 객체로 복제)
setState({ ...state, user: { ...state.user, name: 'Binny' } });
...
스프레드 연산자를 이용해얕은 복사
를 수행한다.- 내부 객체도 독립된 복사가 필요할 때는
중첩해서 복제
해야 한다.
🖨️ 얕은 복사 vs 깊은 복사
구분 | 설명 | 예시 |
---|---|---|
얕은 복사 (Shallow Copy) | 1단계까지만 새로운 객체로 복사됨. 내부 객체는 여전히 참조 공유. | { ...obj } , Array.slice() , Object.assign() |
깊은 복사 (Deep Copy) | 내부 객체까지 완전히 새로운 메모리로 복사됨. | structuredClone() , JSON.parse(JSON.stringify()) |
js
const user = { name: 'Binny', address: { city: 'Seoul' } };
// 얕은 복사
const copy1 = { ...user };
copy1.address.city = 'Busan';
console.log(user.address.city); // "Busan" (같은 주소)
// 깊은 복사
const copy2 = structuredClone(user);
copy2.address.city = 'Busan';
console.log(user.address.city); // "Seoul" (완전 분리)
💡 React와 불변성
React, Redux, Zustand 등 상태 관리 라이브러리들은 모두 불변성을 전제로 한 변경 감지(Shallow Comparison)
를 사용한다.
js
// 상태 관리의 기본 원리
prevState !== nextState; // true면 re-render 발생
- 즉, React는 값이 아니라 참조의 변경을 기준으로 판단한다.
- 따라서 상태 변경 시에는 반드시 새로운 객체를 반환해야 한다.
✍🏼 정리
핵심 개념 | 설명 |
---|---|
불변성(immutability) | 데이터는 직접 수정하지 않고 새로운 값을 만들어 갱신한다. |
원시형은 불변, 참조형은 가변 | 원시형은 값 자체 복사, 참조형은 주소 복사. |
React에서의 이유 | 참조 비교로 변경 감지 → 새로운 객체를 만들어야 렌더링됨. |
복사 방식 | 얕은 복사({...obj} ) / 깊은 복사(structuredClone ) 구분 필요. |