setState는 비동기적으로 동작하기 때문에 state가 직접 수정되어 여러번 상태를 업데이트 하는 경우, 이전 업데이트 내용이 다음 업데이트 내용에 덮어 쓰여질 수가 있다. 즉, 예상치 못한 곳에서 버그가 발생 할 수 있다.
PureComponent에서 동작하지 않는다. PureComponent는 this.state와 setState를 비교해 업데이트가 필요한 경우에만 render함수를 호출해 준다. 이때, state를 직접 수정하게되면 기존의 this.state와 setState가 동일하므로 리액트는 render함수를 호출하지 않는다.
결론, state는 꼭 불변성을 유지하도록 직접 수정하지 말자!
state의 object를 직접 수정하지 않고 새로운 object를 만들어 주려면 object의 할당과 spread 연산자를 알아두면 좋다. (map함수도,,filter함수도 새로운 배열을 반환하기때문에 이럴때 사용하면 좋다👻)
변수에 문자열이나 숫자와 같은 데이터를 할당하게 되면 데이터 자체가 변수에 할당되지만,
object를 변수에 할당하면 변수에는 object메모리가 들어있는 주소(참조값)이 할당된다.
const num = 123; /// 123
const numObj = {num: 123}; /// 1234567(임의의값)이라는 참조값이 할당됨
아래와 같이 배열 안에 객체가 있가 있는경우에는 배열 자체게 object 하나, 그리고 id가 1과 2인 object 각 1개 총 3개의 object가 있으며 따라서 참조값도 3개다.
const array = [ //1234
{id: '1', num: 1}, ///2345
{id: '2', num: 2}, ///3456
];
array2의 참조값은 array와 동일하게 1234이며, spread를 사용해준 array3은 또 다른 참조값 4567을 가지게 된다.
const array2 = array; ///1234
const array3 = {...array}; //4567
spread는 object의 껍데기를 새로운 것으로 변경해주고 그 속의 데이터는 복사해온다. 즉 껍데기의 참조값은 변했지만, 내부에 있는 데이터의 참조값은 array와 동일하다.
const array3 = [ //4567
{id: '1', num: 1}, ///2345
{id: '2', num: 2}, ///3456
];