React
에서 객체나 배열과 같은 참조타입의 상태 값을 변경하기 위해서는 불변성 유지를 필수적으로 해줘야했다. 그렇게 배웠으니.. 그냥 그래야하나보다 생각했는데, 갑자기 왜 그런지 궁금해졌다.
React
는 부모 컴포넌트 또는 state
props
가 변경될 때, 렌더링이 일어나게 된다.
const [obj, setObj] = useState({
name: "pmp4",
age: "22",
skill: {
java: "A",
oracle: "B",
spring: "A",
javascript: "A",
}
});
만약 위 상태 값의 skill.oracle
값만 변경했다고 가정한다. 변경되었다는 걸 인지하기 위해, 모든 속성(name, age, skill.java, ...)을 비교하게 된다면 비효율적이다.
React
에서는 이런 비효율적인 과부하를 덜어내기 위해 이전객체와 현재객체의 깊은비교가 아닌 얕은비교를 하게된다.
React
에서 원시 자료형의 상태 값 변경은 setState
를 사용하여 변경하면 된다. 원시 자료형에서는 값을 비교하여 상태를 감지하기 때문이다.
하지만 참조 자료형의 상태 감지는 그 안의 각각의 값들이 아닌 래퍼런스(참조주소)를 비교한다.
obj.skill.oracle = "A";
prevState === currentState //true : 참조 값이 같으므로, 렌더링을 진행하지 않는다.
setObj({...obj, skill: {...obj.skill, oracle: "A"}});
prevState === currentState //false : 참조 값이 다르므로, 렌더링을 진행한다.
위 코드처럼 참조 값이 다르게 해야하므로, 새로운 변수에 spread Operator
를 사용하여 기존 상태 값을 복사하여 값을 변경하거나 map
filter
slice
reduce
와 같은 새로운 값을 반환하는 메서드를 통해 값을 변경해줘야한다.