
가장 큰 이유는 state는 변동사항이 생기면 state를 데이터 바인딩 해놓은 html도 자동으로 재렌더링 해주기 때문이다.
기존의 js에서 변수바인딩 + 변수가 변경 된 상황에선 js코드로 "변수 내용 바뀌었으니까 html도 고쳐주세요 ~"라고 코드를 짰어야했다.
function App(){
let [title, setTitle] = useState('남자 코트 추천');
return (
<h4>{ title }</h4>
)
}
참고로 let [title, setTitle] = useState('남자 코트 추천'); 요 방식은 destructuring 문법으로 array 안에 있는 데이터들을 변수로 쉽게 저장할 수 있는 문법이다.
예를 들어 ['Son', 25]이렇게 생긴 array자료를 각각 변수에 저장하고 싶으면
let array = ['Son', 25];
let name = array[0];
let age = array[1];
보통 이렇게 한다. 하지만
let [name, age] = ['Son', 25];
이런 식으로, destructuring 문법을 통해 간단하고 깔끔하게 할당도 가능하다!
하지만 state는 위와같이 데이터 바인딩을 해놓았고 title이 다른걸로 변경된다면 자동으로 html을 재 렌더링 해준다 이거다
그래도 된다.
하지만 state의 장점이 뭐냐? 변경된 데이터를 자동으로 재 렌더링 해준다는거 아니냐
그렇다면 ?
이를테면 사이트의 로고, 이름같은 몇년에 한번 바뀔까 한 그런 것들은 그냥 변수 선언해도 된다.
중요하다.
state변경은 state 변경함수를 써서 해야한다.
let [name, setName] = useState("손배준");
바로 저 setName 저 친구가 state 변경함수이다.
즉, name이란 state를 바꾸고싶다 ? 그럼 state 변경함수를 통해 변경하면 된다.
왜 꼭 변경함수로 해야하냐? 그래야 html 재렌더링이 된다!!
array, object 타입인 state를 일반 문자열이나 숫자처럼 변경하면 변경이 안된다.
버그가 아니다.
기존 state == 바꾸려는 변수
이기 때문이다.
이걸 알려면 array와 object 자료형의 동작원리를 알아야 하는데,

내가 변수로 let arr = [1, 2, 3];을 선언하면
실제 배열 [1, 2, 3] 값은 RAM에 저장되고
let arr 변수는 값이 저장되어 있는 RAM의 주소를 가리킨다.
따라서
let copy = arr;
copy[0] = 0;
setArr(copy);
이 코드로 따지자면 copy는 arr과 같은 RAM을 가리키게 된다는 것이다.
근데 ? 위에 말했듯, 변수는 그저 가리키는 화살표를 가질 뿐이고, 그 말은 arr과 copy는 같은 화살표를 갖고있는, 즉 == 비교시 true 값이 나온다!
따라서 setArr(copy)를 해봤자 같은 값이라 판단되기 떄문에 html에서 재렌더링 하지 않는 것이다.
let data1 = [1,2,3];
let data2 = data1; // 복사
data2[0] = 1000; // data2 내부 변경
console.log(data1); // [1000, 2, 3]
console.log(data2); // [1000, 2, 3]
console.log(data2 === data1) // true
그럼 어떻게 해야 되느냐 ~?
를 사용한다.
그게 뭐냐
let copy = [...arr];
copy[0] = 0;
setArr(copy);
처럼 [...array] 형식으로 복사를 한다.
뜻은 괄호를 벗겨주세요~ 이다.
즉, arr에 있는 자료들을 괄호 벗긴 담에 다시 배열로 만들어주세요 ~
하면 ? 새로운 array로 인식을 한다. 즉, 화살표 자체가 바뀐다는 것이다.
따라서 저렇게 하면, state변경을 요청했을 때, 완전히 다른 독립적인 array로 인식을 할 것이고, 값이 변경되게 된다. (독립적인 사본을 shallow copy || deep copy라고 한다고 한다.)