1. useState를 사용해서 상태관리를 할 때, 객체나 배열의 상태가 업데이트 되는 경우 새로운 변수를 만들고 그 변수에 업데이트 되는 값을 넣은 뒤 그 변수를 상태변화함수에 넣어주도록 한다.
숫자나 문자열은 따로 새로운 변수를 만들지 않고, 바뀌는 값을 그대로 넣어도 되는데 왜 객체나 배열은 이렇게 새로운 변수를 만들어 줘야할까?
→ 리액트는 상태가 변경될 때 컴포넌트의 리렌더링이 결정된다. 상태 객체를 직접 변경하면 리액트가 이전 상태와 새로운 상태를 비교할 때 차이점을 감지하지 못할 수 있다. 왜냐하면 리액트의 상태 비교 알고리즘이 얕은 비교를 수행하기 때문이다. 즉, 객체의 참조가 변경되었는지만 확인한다. 객체의 내부 속성이 변경되어도 참조가 같다면 리액트는 상태가 변경되지 않았다고 판단하고 재렌더링을 하지 않는다. 이 문제를 피하기 위해 새로운 객체를 생성하는 것.
* 얕은비교(shallow comparison): 문자열/숫자 등 원시자료형은 값을 비교하고, 객체/배열 등 참조자료형은 참조의 위치를 비교하는 것. 참조자료형의 값까지 비교하는 것은 깊은 비교라고 한다.
// 객체 sums의 상태 관리
const [sums, setSums] = useState({});
useEffect(() => {
//상태 sums에 업데이트 시킬 새로운 변수를 만들어준다
const newSums = {};
// newSums에 들어갈 데이터 가공. 어쩌구 저쩌구..
// newSums을 상태 변화함수에 넣어 sums의 상태를 변화시킨다
setSums(newSums);
}, []);
2. useState의 초기값을 설정할 때 props나 바뀌는 데이터로 설정하면 안된다.
const [isActive, setIsActive] = useState(data?.DEL === “Y”);
data가 계속 바뀌는 값일 때, isActive에 data?.DEL === “Y”를 넣으면 바뀌는 값에 따라 isActive가 바뀔 것이라고 생각하지만 그렇지 않다. useState의 초기값은 컴포넌트가 마운트될때(제일 첫 렌더링) 딱 한번만 작동한다. 데이터나 props가 변경된다고 이 초기값도 같이 업데이트 되는 것은 아니다.
→ 그래서 상태가 props 또는 상태가 변경될 때마다 상태값도 업데이트 시키고 싶다면 useEffect를 사용하여 해당 프롭스 또는 데이터를 의존성배열에 넣어주고 상태를 업데이트 시키는 로직을 추가하여야한다.
// 1.
<ModalHeader>{item?.BRD_NAME}</ModalHeader>
// 2.
<Checkbox defaultChecked={item?.BRAND_NEW === "Y"} />
1. 이렇게 JSX에서 직접 props를 참조하여 렌더링하는 경우는 props가 변경될 때 재랜더링(업데이트)된다.
2. 그런데 2번의 defaultChecked 얘도 JSX인데 업데이트는 안된다. 이것도 useState의 초기값과 마찬가지로 체크박스가 처음 렌더링 될때 즉 마운트될 때만 고려되는 속성이다. 그래서 defaultChecked 대신 checked 속성을 사용한다. 이렇게 보니 초기값 설정은 모두 마운트 될때만 설정되는 속성인 것같다. 초기값에는 유동적인 값은 넣지 않거나 따로 변경하는 작업을 해줘야겠다.
* 참고
https://choisuhyeok.tistory.com/34
[React] useState 초기값으로 props를 사용하면 안된다.
props로 받아온 값을 useState의 초기값으로 사용하여 렌더링 할 때 값이 분명 변경되었는데 useState에 들어간 값이 변하지 않는 문제가 생겼다. 이유는 useState의 초기값으로 props를 사용했기 때문이
choisuhyeok.tistory.com
-
이렇게보니 엄청 기초적인 내용인데, 막상 개발할때는 생각이 나지 않는 것 같다. 내가 알고있는 것을 실제로 코딩할때 적용하도록 노력해야겠다.
'React' 카테고리의 다른 글
| useState에서 상태 변경 시 바로 재렌더링 일어나지 않는 버그 (2) | 2025.08.13 |
|---|---|
| throttle과 debounce 사용하기 (2) | 2025.06.21 |
| [한입리액트] 최적화 : useMemo, React.memo, useCallback, useReducer, context API (0) | 2023.10.18 |
| [한입리액트] useRef : 컴포넌트가 리렌더링 되더라도 값이 초기화되지않고 유지시키고 싶을 때 사용 (2) | 2023.07.27 |
| [React-Query] 2. useMutation 사용하기(공부중...) (0) | 2023.06.27 |