오늘은 javascript에서의 원시타입과 객체타입이 뭔지, 리액트와 불변성에 대해서 공부해 봤다.
개인적인 공부를 위해 작성하는 블로그입니다. 혹시라도 잘못되거나 부족한 부분이 있다면 댓글로 알려주시면 감사하겠습니다.
💁🏻 원시타입과 객체타입
불변성을 이해하려면 먼저 자바스크립트에 원시타입과 객체타입을 알아야 한다.
자바스크립트가 제공하는 7가지 데이터 타입은 크게 원시타입(primitive type)과 객체타입(Object/reference type)으로 구분할 수 있다. (객체타입에는 객체와 배열이 해당됨)
원시타입인 score에 100이라는 값을 할당할 때 기존 주소에서 100을 할당받은 주소로 변경된다.
원시타입: 한번 할당된 원시 값은 읽기 전용(read only)으로 변경할 수 없다.
따라서 원시 값을 변경해야 한다면 새로운 메모리공간을 할당받아 변경 후 해당주소로 참조를 바꾼다.
객체타입: 주소를 참조하는 형태로 변경 가능한(mutable) 값
객체타입은 할당된 메모리 주소를 참조하는 방식으로 여러 변수가 동일한 객체를 참조할 수 있다.
💡 정리하자면 불변성은 데이터가 생성된 후에는 변경되지 않는 것을 의미한다.
👨🏻💻 불변성이 중요한 이유
const obj = {}
obj.a = 1
console.log(obj) // { a: 1 }
이처럼 데이터가 할당된 이후 값이 언제, 어디서 변경될지 모르기 때문에 코드예측이 어려워지고 복잡도가 올라가 디버깅이 어려워져 버그가 발생하기 쉬워진다.
👩🏻🚀 리액트와 불변성
React에서 컴포넌트가 리렌더링 될 때마다 새로운 VDOM을 만들고, 이전의 VDOM과 비교하여 변경사항을 찾는 재조정(Reconciliation)이 이루어진다. 이때 상태 변경 감지를 위해 state의 메모리 주소를 비교하는 얕은 비교가 실행된다.
객체 타입의 경우 값을 수정하더라도 메모리의 주소가 같기 때문에 불변성을 지키기 위하여 JSON.parse(JSON.stringify(obj)) 나 structuredClone(obj)과 같이 새로운 객체를 생성하거나 배열의 경우 spread, map, slice, reduce... 와 같이 새로운 배열을 반환 하는 메소드를 활용하여 불변성을 유지해야 한다.
// 원시타입
const [number, setNumber] = useState(0)
setState(3)
// 참조타입
const [person, setPerson] = useState({ name: '', age: 20 })
setPerson({...person, name: 'seungho'})