본 내용은 이전의 React - State의 기초 와 이어집니다
자바스크립트의 자료형은 크게 기본형(Primitive type)과 참조형(Reference type)이 있다는 건 모두가 알고 있을 것이다.
기본형은 별거 없는데 문제는 바로 참조형.
참조형 값들은 그 특성들이 좀 독특해서 변수로 다룰 때도 조금 주의해 주어야 하는데, 이것은 state를 활용할 때도 마찬가지이다.
아래 코드는, 로그인 히스토리에 로그를 추가하려는 한 참조형알못의 코드이다.
const [loginHistory, setLoginHistory] = useState([]);
const historyHandler = () => {
loginHistory.push(log);
setLoginHistory(loginHistory);
};
// 실행 안됨 ㅎ
위 코드처럼, 배열 값을 가진 loginHistory state에 push()를 통해 배열의 값을 변경한 다음, 변경된 배열을 setLoginHistory setter 함수로 state를 변경하려고 하면 코드가 제대로 동작하지 않는다.
왜일까?
LoginHistory state는 배열 값 자체를 가지고 있는 게 아니라,
그 배열의 주솟값을 참조하고 있기 때문이다.
그렇기 때문에 push()로 백날 배열 안에 요소를 바꿔준다고 하더라도 결과적으로 참조하는 배열의 주솟값은 변경된 것이 아니게 된다는 것이다.
결과적으로 react 입장에서는, loginHistory State가 참조하는 주솟값은 응당 똑같기 때문에, State가 바뀌었다고 판단하지 않는 것이다!
결론은, 참조형인 state를 사용할 때에는 반드시 새로운 참조형 값을 만들어 state를 변경해야 한다.
그 중 가장 간단한 방법은 Spread 문법(...) 을 활용하는 것이다. 어떻게? 아래처럼!
const [loginHistory, setLoginHistory] = useState([]);
const historyHandler = () => {
setGameHistory([...gameHistory, nextNum]);
};
// 실행 잘됨!
이 참조형 state의 특성을 이해하지 못하면, 간혹 state가 제대로 변경되지 않는 버그가 발생했을 때 원인을 제대로 찾지 못하는 경우가 발생할 수도 있다.
참조형 state를 활용할 땐 반드시 새로운 참조형 값을 만들어서 state를 변경해야 한다는 점. 꼭 기억해 두길 바란다.
설명 감사합니다 !