05. array/object 변경
서론
저번 실습 과제를 하면서 array 타입의 state를 변경하는 함수에 대해서 공부해봤다. spread 문법을 쓰지 않고 그냥 array를 수정하게되면 state 변경함수가 제대로 작동하지 않는데 이 작동원리와 문법에 대해서 좀 더 자세히 공부했다.
본론
state 변경함수 동작원리
간략하게 정리를 했었는데 다시 한번 살펴보자면 state 변경함수를 쓸 때
먼저, 기존 state === 변경 state 검사를 진행한다. 이때 true가 나오게 되면 변경을 해주지 않고, false가 나올 때 state를 변경시켜 html을 재렌더링해준다.
이 부분을 조금 더 자세히 살펴보면 array/object 동작원리에 대해서 살펴봐야한다.
자바스크립트는 array/object 자료를 생성하게 되면 RAM이라는 가상공간에 저장이 되고, 변수에는 데이터의 주소가 담기게 된다.
따라서 array/object 자료를 복사하게 되면 데이터 값을 복사하는 것이 아니라 주소를 공유하게 되는 것이다.
let data1 = [1, 2, 3];
let data2 = data1;
위처럼 data1을 복사해서 data2를 만들었다고 가정했을 때 사실상 둘은 값을 복사한 것이 아니라 주소를 복사했기 때문에 data1을 수정하든 data2를 수정하든 같은 값을 가지게 된다.
let data1 = [1, 2, 3];
let data2 = data1;
data2[0] = 1000;
console.log(data2 === data1); //true 나옴
아마 data1과 data2를 찍어보면 둘 다 [1000, 2, 3]이라고 나올 것이다. 따라서 둘은 같은 값을 가지므로 이러한 방법으로 state 변경함수를 사용하게 되면 변경이 되지 않는 것이다.
spread 문법!
이럴 때 사용하는게 spread 문법이다. let data2 = [...data1] 후에 data2[0]를 1000으로 바꿔주고 둘을 비교해주면 false가 나올 것이다. 이는 같은 주소를 공유하는 것이 아니라 새로운 주소를 가지기 때문이다.
Q. 점 3개를 왜 쓰는거죠?
A. 점 3개의 뜻은 괄호를 벗겨달라는 뜻이다. ...[1, 2, 3] 이라고 쓰면 괄호를 벗기고 1, 2, 3이 남는다. 첫번째로 괄호를 벗기는 역할을 수행하는 연산자인데, 두번째로는 array/object 자료형을 복사할 때 사용된다. 위 예시처럼 [...data1]을 하게 되면 data1에 있던 자료들의 괄호를 벗긴 후에 array로 만들어달라는 뜻으로 새로운 array를 생성하는 것이므로 주소값이 달라져 data1 === data2는 false가 나오게 되고 state 변경함수를 사용할 수 있게된다.
이러한 독립적인 사본을 shallow copy / deep copy라고 한다.
정리
리액트에서 array/object state를 수정하고 싶을때는 독립적인 카피본을 만들어 수정한다.
[...기존state] {...기존state} 로 사용하면 된다.
** 실습
글목록을 가나다 순으로 정렬하는 버튼 생성하기
글목록을 하나 변경하는 것과 똑같이 진행해줬다. sort() 함수를 이용해서 array를 정렬하고 정렬된 array를 state 변경함수를 이용해 넣어줬다.
{/* 가나다순 정렬 버튼 생성 */}
<button onClick={() => {
let sortedTitle = [...title.sort()];
changeTitle(sortedTitle);
}}>정렬</button>
spread 문법을 이용해 먼저 title을 정렬해주고 이를 다시 array로 만들어 sortedTitle에 저장해준다. 이후 state 변경함수인 changeTitle() 안에 변경된 array를 넣어주면 버튼을 클릭할 때마다 글자가 정렬되는 것을 확인할 수 있다.