: 메모리에 있는 값을 변경할 수 없는 것
→ 원시데이터는 불변성이 있고 원시데이터가 아닌 객체, 배열, 함수는 불변성이 없다.
let number = 1;
let secondNumber = 1;
console.log(number === secondNumber) //true
number와 secondNumber는 같은 공간을 바라보고 있다. 메모리에 이미 1이라는 값이 있으므로 secondNumber에 1을 할당한다고 해도 별도의 값을 다시 생성하는 것이 아니다.
위의 코드에 이어서 데이터를 수정하는 경우
number = 2;
let obj1 = {
name: "kim",
}
let obj2 = {
name: "kim",
}
console.log(obj1 === obj2); //false
메모리에 동일한 값이 있지만 별도의 공간에 따로 저장된다.
위의 코드에 이어서 데이터를 수정하는 경우
obj1.name = "park";
원시 데이터는 불변성이 있지만 원시 데이터가 아닌 것은 불변성이 없다
React에서는 컴포너트가 화면에 그려지기 위해서 렌더링(화면 갱신)을 한다.
렌더링 되는 조건은 state가 바뀌면 된다. (state가 변경됨 → 화면 갱신 / 변경 없음 → 화면 갱신x) state의 변경 여부를 메모리 주소 비교를 통해 확인하는데 데이터를 수정해도 불변성을 지키지 않으면 렌더링이 발생하지 않게 된다. 앞에서 말한 것 처럼 원시데이터가 아닌 것들은 값이 바뀌어도 메모리 주소가 바뀌지 않으므로 불변성을 지킬 수 있게 만들어줘야 한다.
"값이 바뀌면 아예 다른 주소를 바라보게 하자"
스프레드 문법, filter, map등을 사용해 새로운 객체를 만들어 state를 변경하면 객체나 배열의 값이 바뀌었을 때 정상적으로 렌더링 되게 할 수 있다.
import React, { useState } from "react";
function App() {
const [obj, setObj] = useState({
name: "soul",
age: 100,
});
return (
<div>
<div>{obj.name}</div>
<button
onClick={() => {
obj.name = "soulful";
const obj2 = { ...obj }; //스프레드
setObj(obj2);
}}
>
변경!
</button>
</div>
);
}
export default App;