불변성은 자바스크립트 개발에서, 특히 React와 같은 프레임워크를 사용할 때 매우 중요한 개념입니다. 오늘은 실제 프로젝트에서 겪었던 경험을 바탕으로 불변성을 지키며 상태를 관리하는 방법에 대해 알아보겠습니다.
🔍 불변성이 왜 중요할까?
- 예측 가능한 상태 변화
- 의도치 않은 부작용 방지
- React의 렌더링 최적화
‼️ 잘못된 상태 관리의 예시
// ❌ 잘못된 방법
const handleUpdateUser = (user) => {
user.name = "새로운 이름"; // 직접 객체 수정
setUser(user); // React가 상태 변경을 감지하지 못할 수 있음
}
// ❌ 배열 수정 시 흔한 실수
const handleAddItem = (items) => {
items.push(newItem); // 원본 배열 직접 수정
setItems(items); // 불변성 위반
}
✨ 올바른 상태 관리 방법
1. Object Spread 연산자 활용
// ✅ 올바른 방법
const handleUpdateUser = (user) => {
setUser({
...user,
name: "새로운 이름"
});
}
// 중첩된 객체의 경우
const handleUpdateAddress = (user) => {
setUser({
...user,
address: {
...user.address,
city: "새로운 도시"
}
});
}
2. 배열 상태 관리
// ✅ 배열에 항목 추가
const handleAddItem = (items) => {
setItems([...items, newItem]);
}
// ✅ 배열에서 항목 제거
const handleRemoveItem = (items, id) => {
setItems(items.filter(item => item.id !== id));
}
// ✅ 배열의 특정 항목 수정
const handleUpdateItem = (items, updatedItem) => {
setItems(
items.map(item =>
item.id === updatedItem.id
? { ...item, ...updatedItem }
: item
)
);
}
3. 불변성 라이브러리 활용
복잡한 중첩 객체의 경우, Immer 같은 라이브러리를 활용하면 더욱 편리합니다:
import produce from 'immer';
const handleComplexUpdate = (user) => {
setUser(
produce(user, draft => {
draft.addresses[0].city = "새로운 도시";
draft.contacts[0].phone = "새로운 번호";
})
);
}
🚀 실전 팁
- 얕은 복사와 깊은 복사 이해하기
// 얕은 복사 const shallowCopy = { ...originalObject };
// 깊은 복사
const deepCopy = JSON.parse(JSON.stringify(originalObject));
// 주의: 함수나 Date 객체 등은 제대로 복사되지 않습니다
2. 성능 최적화
```javascript
// 불필요한 객체 생성 피하기
const handleToggle = (id) => {
setItems(prevItems =>
prevItems.map(item =>
item.id === id
? { ...item, isActive: !item.isActive }
: item
)
);
}
❌ 흔한 실수와 해결방법
- 중첩된 객체 수정 시 일부 레벨 누락
// ❌ 잘못된 방법 setUser({ ...user, address: { city: "새로운 도시" } // 다른 address 속성들이 사라짐 });
// ✅ 올바른 방법
setUser({
...user,
address: {
...user.address,
city: "새로운 도시"
}
});
2. 배열 내 객체 수정 시 참조 문제
```javascript
// ❌ 잘못된 방법
const updateItem = items.find(item => item.id === id);
updateItem.value = newValue;
setItems([...items]); // 참조가 같아서 React가 변화를 감지못함
// ✅ 올바른 방법
setItems(items.map(item =>
item.id === id
? { ...item, value: newValue }
: item
));
마치며
불변성을 지키는 것은 처음에는 번거롭게 느껴질 수 있지만, 애플리케이션의 예측 가능성과 디버깅의 용이성을 크게 향상시킵니다. 특히 React와 같은 현대적인 프레임워크에서는 필수적인 개념이므로, 처음부터 올바른 습관을 들이는 것이 중요합니다.
다음 글에서는 "클로저(Closure)를 활용한 실용적인 디자인 패턴"에 대해 다루도록 하겠습니다.
'개발일지' 카테고리의 다른 글
Promise와 async/await로 비동기 처리 마스터하기 (0) | 2024.12.12 |
---|---|
Java Reflection API 개발일지: 동적 프로그래밍의 실전 여행 🔍 (0) | 2024.12.11 |
Java 개발일지: CompletableFuture로 구현하는 비동기 프로그래밍 여정 📘 (0) | 2024.12.10 |
Java Records: 현대적 데이터 클래스의 새로운 패러다임 📝 (0) | 2024.12.10 |
Java Optional: 우아한 null 처리의 완벽 가이드 ✨ (0) | 2024.12.10 |