리액트에서 useState의 setter 함수를 사용해서 값을 변경해도 보이는 값은 변경되지 않는 일이 발생할 때가 있음
콘솔을 찍어봐도 값이 바뀌었지만, 화면에 표시되고 있는 값이 바뀌지 않는다면
분노를 잠시 추스리고, 리액트가 상태변경을 어떻게 감지하는지 알아야 리액트의 밀당을 이해할 수 있다
type User = {
name: string;
age: number;
};
const [user, setUser] = useState<User>({ name: "John", age: 20 });
위와 같은 코드에서, 인풋값으로 새로운 나이를 받는다고 생각해보자
const onClickChangeAge() => {
//잘못된 예제
user.age = Number(inputRef.current?.value);
setUser(user);
};
이런식으로 상태값을 변경해주려고 하면 user의 age값은 변경되지만 화면에 표시되고 있는 age는 변경되지 않는다
이유는 리액트는 참조값을 기반으로 상태 변경을 감지하기 때문인데,
useState의 setState(next)가 호출되면, React는 이전 상태와 다음 상태를 Object.is(prev, next)로 비교함
두 값이 동일(reference 동일) 하면 “변경 없음”으로 보고 리렌더를 생략함
숫자/문자열 같은 원시값은 값 자체가 비교 대상이지만, 객체/배열은 참조(메모리 주소)가 비교 대상임
당신이 출가해서 살다가 부모님 집에 몰래 쏙 들어가서 다시 살아도 동사무소는 그걸 모르는 것과 같은 이치임
전입신고, 거주지변경 신고를 해서 그 집은 이제 3명이 사는게 아니라 4명이 사는 새로운 집이다 라고 리액트에게 알려줘야하는 것임
const onClickChangeAge = () => {
// 올바른 예제
setUser({ ...user, age: Number(inputRef.current?.value) });
};
그러니까 새로운 user 객체를 생성하고 그것을 setter 함수에 전달해야
리액트는 상태가 변경되었다고 감지하고 화면을 업데이트한다
객체의 값을 변경할 때는 직접 수정(mutation)하지 말고, 새로운 객체와 배열로 교체하여
리액트에게 새로운 값으로 바뀌었다고 알려주자
'🖥️ Front-End > React' 카테고리의 다른 글
[React/Hooks] 불필요한 리렌더링 방지하는 방법과 useCallback (1) | 2025.08.12 |
---|---|
[React/Hooks] useEffect로 값을 변경할 때 무한루프가 발생하는 이유와 useEffect (2) | 2025.08.11 |
[JS/React-Query] 1. useQuery (0) | 2025.02.27 |
[JS/React-Query] 0. QueryClient (2) | 2025.02.02 |
[JS/Zustand] 1. Zustand 주요 함수 정리 (0) | 2025.01.18 |