
이번엔 상태불변성에 대해서 알아보고
도대체 어떤 녀석이길래 중요한지에 대해서 학습해보자잉!

많은 파트에서 상태불변성에 대해서 학습했었다.
오늘 내가 집중해 볼 것은 React 혹은 프론트엔드에서의 상태 불변성이다.
프로그래밍 측면에서의 상태불변성은 메모리에서 값이 변하지 않는 것이다.
자바스트립트로 예를 들어보자!
자바스크립트에서 원시 타입의 변수는 불변성을 갖는다.
let a = 1;
a = 2;
a에 새로운 값 2를 대입하면 a 메모리 공간에 값을 2로 변경하는 것이 아니라 새로운 메모리 공간을 만들고 그 메모리에 2를 대입하는 방식으로 불변성을 지킨다.
하지만 원시 변수가 아닌(객체, 배열, 함수) 다른 참조형 값들은 다르게 동작한다.
const obj = {
a: 1
}
obj.a = 2
객체 obj의 a에 2를 대입했을 때 원시 타입과는 다르게 a 속 값이 변경된다.
이는 마치 call by reference 와 call by value와 같다!
전공 과목이 도움이 되는구나 ㅎㅎ

이처럼 자바스크립트 객체는 가변한다. 리액트에서는 자바스크립트 객체가 가변하기 때문에 문제가 된다.
그렇다면 react에서는 이러한 자바스크립트의 가변 문제를 어떻게 다루고 있을까?
react는 상태 업데이트를 수행할 때 얕은 비교 방식을 사용한다.
얕은 비교 배열이나 객체의 속성 하나하나를 비교하는게 아니라, 이전 참조값과 현재 참조값만을 비교하여 상태 변화를 감지합니다.setState([...state, newState]) 이런 식으로 새로운 참조값을 가진 배열이나 객체를 생성하는 것입니다.이렇게 상태불변성을 유지하고 업데이트 할 수 있다.
리액트는 배열이나 객체를 업데이트 할 때, 새로운 참조값을 가진 배열이나 객체를 생성해 상태변화를 감지한다. 새로운 참조값을 가진 배열이나 객체를 생성하므로 원본 데이터의 참조값에 영향을 주지 않기에 불변성을 지킨다는 것이다.
효율적인 상태 업데이트
상태의 변화에 따라 컴포넌트가 렌더링, 리렌더링된다.
만약 참조 타입의 데이터라변 수정 시 변경을 감지하지 못할 수 있다.
사이드 이펙트 방지
원시타입은 애시당초 불변성 특징을 가지고 있지만 참조타입인 객체나 배열의 경우 값을 변경할 때 원본데이터가 변경될 여지가 있다. (불변성이 지켜지지 않을 수 있습니다.) 이렇게 원본 데이터가 변경될 경우, 이 원본데이터를 참조하고 있는 다른 객체에서 예상치 못한 오류가 발생할 수 있다.
// 원시타입
const [number, setNumber] = userState(0);
setState(3);
// 참조타입
const [person, setPerson] = useState({name: '', age: 26})
setState({...person, name: 'kim'})
상태불변성은 효율적인 상태 업데이트와 사이드 이펙트를 방지하기 때문에 중요합니다.
리액트는 상태 업데이트에 “얕은 비교”를 수행하기 때문에 참조 타입의 값인 경우 의도적으로 불변성을 지켜야합니다.
”얕은 비교”란 객체, 배열의 속성을 하나하나 확인하는 것이 아닌 이전 참조와 현재 참조의 차이를 비교하는 방법입니다. “얕은 비교”에 효과적으로 상태를 업데이트하기 위해서는 spread 연산자, filter, map 등 새로운 배열을 반환하는 도구들을 사용합니다.
새로운 참조를 만들기 때문에 상태불변성을 지킬 수 있습니다.