불변성(immutability)란?
불변성이란 한번 생성된 원본의 데이터는 변경 시키지 않고, 데이터 변경 시 새로운 원본을 만드는 디자인 패턴이다.
불변성X -> mutable
- 원본 데이터가 변할 수 있다는 의미
- 배열의 push 메소드
const arr = [1,2,3,4,5];
arr.push(6);
console.log(arr); // [1,2,3,4,5,6]
// push 메소드는 원본 배열인 arr의 값 자체를 변경시킨다.
불변성O -> immutable
- 원본 데이터가 변할 수 없다는 의미
- 배열의 map 메소드
const arr = [1,2,3,4,5];
arr.map(el => el * 2); // [2,4,6,8,10] 이 리턴됨.
console.log(arr); // [1,2,3,4,5]
// map 메소드는 원본 배열인 arr의 값을 변경시키지 않는다.
리액트에서 불변성을 지키는 것이 왜 중요한가?
1. 리액트 Life Cycle에 따른 리렌더링 규칙 -> 리렌더링이 안될 수 있다.
- 리액트는 state 변경 전 후의 값을 얕은 비교하여 다른 경우에만 리렌더링한다.
- 얕은 비교랑 참조값의 경우 주소끼리 비교하고, 원시값은 데이터 그 자체끼리 비교하는 것.
const [state, setState] = useState({a: 1, b: 2});
// 초기 state {a: 1, b: 2} 는 참조값으로 0x1234 와 같은 주소값을 가리킴.
state.a = 10; // state 값을 직접 변경해도 state는 여전히 0x1234
setState(state); // 기존 state 와 변경요청온 state 모두 0x1234 이므로 리렌더링이 발생하지 않음
2. Side Effect
- 객체형 상태 내부의 값에 접근해서 직접 데이터를 변경할 경우, 이 객체와 연결되어 있는 다른 데이터가 변경됨에 따라 예상치 못한 버그(부작용)을 일으킬 수 있다.
- 객체의 내부 데이터에 직접 변경을 가하는 방식으로 개발할 경우, 명령형/절차적 프로그래밍을 하게 되어 규모있는 프로젝트를 만들게 되면 유지보수가 어려워진 스파게티 코드를 보게 될 확률이 높다.
불변성을 지키는 수단에는 어떤 것들이 있을까?
1. Spread Operator
- 얕은 복사를 손쉽게 구현할 수 있다.
const [obj, setObj] = useState({
name: "James",
age: 30
})
const increaseAge = () => {
setObj({...obj, age: obj.age + 1});
// setObj({name: "James", age: 30, age: obj.age + 1});
}
-depth가 깊은 객체라면? 다소 가독성이 떨어지고 복잡해 보인다.
const [obj, setObj] = useState({
name: "James",
contact: {
email: "abc@gmail.com",
phone: "010-1234-5678"
}
})
const changeEmailTo = (newEmail) => {
setObj({ ...obj, contact: {...obj.contact, email: newEmail} })
}
참고자료
배열 메소드가 mutate한지 알려주는 사이트
TIL을 작성하며
챌린지 두번째 수업을 들었다. ai 없이 기본적인 코드도 짤 줄 모르는 내 모습에 1차 현타가 왔고, 아주 기본적인 개념을 놓치자 2차 현타가 왔다. 그 중 하나가 놀랍게도 불변성 관련한 부분이었다. 특강이 있었는데 그걸 들었는지조차 기억이 안 난다. 아마 안 들었을 것이다. 국비가 아깝다. 정신 좀 차리렴
'웹개발 > react' 카테고리의 다른 글
[react] Custom hook (0) | 2024.02.27 |
---|---|
[React] React Query (0) | 2024.02.26 |
[React] Redux Toolkit (0) | 2024.02.16 |
[React] Custom Sidebar 구현하기 (0) | 2024.02.13 |
[React] Custom Modal 창 구현하기 (1) | 2024.02.13 |