불변성 : 메모리에 있는 값을 변경할 수 없는 것.
자바스크립트의 데이터 형태 중 원시 데이터는 불변성 🙆🏻♀️
원시 데이터가 아닌 객체, 배열, 함수는 불변성 ❌
만약 let A = 1
이라고 선언하면 메모리에는 1
이라는 값이 저장된다.
그리고 변수 A는 메모리에 있는 1을 참조
한다.
그리고 나서 let B = 1
이라는 다른 변수를 선언하면 이때도 자바스크립트는 ⭐이미 메모리에 있는 1이라는 값을 참조⭐한다.
즉, A와 B는 변수의 이름은 다르지만 같은 메모리 값을 바라보고 있기 때문에 A===B의 결과는 true
이다.
하지만 원시데이터가 아닌 값은 다르다.
let obj_1 = {name: ‘kim’}
이라는 값을 선언하면 메모리에 obj_1
이 저장된다.
그리고 let obj_2 = {name: ‘kim’}
이라고 같은 값을 선언하면 obj_2
라는 ⭐새로운 메모리 공간에 저장⭐된다. 그래서 obj_1===obj_2의 결과는 false
가 된다.
기존에 1이던 A를 2로 수정하려고 하면, 메모리에 저장된 1은 변하지 않고 ⭐새로운 메모리 저장공간⭐에 2가 생기고 A는 2를 참조하게 된다. 그래서 B를 찍어보면 여전히 1이라고 콘솔에 보인다.
A와 B는 이제 각각 다른 메모리 공간을 참조하고 있다. => 불변성
그런데 obj_1을
수정하면? 기존 메모리 저장공간에 있는 값이 바뀐다.
원시데이터 - 수정했을 때 새로운 메모리 저장공간에 새로운 값을 저장한다.
원시데이터가 아닌 데이터 - 수정했을 때 기존에 저장되어있던 메모리 저장공간의 값 자체를 바꾼다.
리액트에서는 화면을 리렌더링 할지 말지 결정할 때 state
의 변화를 확인한다.
state가 변했으면 리렌더링. 변하지 않았으면 리렌더링 하지 않는다.
이 때, state가 변했는지 안변했는지 확인하는 방법은 메모리 주소를 비교하는 것이다.
리액트에서 원시데이터가 아닌 데이터를 수정할 때 불변성을 지켜주지 않고 직접 수정하면 값은 바뀌지만 메모리 주소는 변함이 없어 리액트는 state가 변했다고 인지하지 못한다.
따라서 일어나야 할 리렌더링이 일어나지 않게 된다.
배열을 setState
할 때 직접 수정을 가하지 않고 전개 연산자를 사용해 기존의 값을 복사하고, 그 이후에 값을 수정한다.
전개 연산자를 사용하면 내용은 복사하지만 완전히 새로운 메모리 주소를 할당한다.
import React, { useState } from "react";
function App() {
const [dogs, setDogs] = useState(["말티푸"]);
function onClickHandler() {
setDogs([...dogs, "밤빵이"]); // 전개 연산자를 이용해서 dogs를 복사 -> 이후 항목 추가
}
console.log(dogs);
return (
<div>
<button onClick={onClickHandler}>버튼</button>
</div>
);
}
export default App;
하나 이상의 인자를 받고, 인자를 변경하지 않고 참조하여 새로운 값을 반환하는 함수.
같은 input 동일한 인자가 전달되면 항상 동일한 결과를 반환하는 함수.
const addSixPure = (arr) => {
newArr = [...arr, 6]; // 전개 연산자로 새로운 배열에 6 추가
return newArr;
};
const num_arr = [1, 2, 3, 4, 5];
const addSixImpure = (arr) => {
arr.push(6); // 매개변수에 직접 6 추가
return arr;
};