728x90
모던 리액트 딥다이브 책 읽으면서 얕은 복사에 대한 내용이 이해가 되지 않았다. 얕은 복사를 하는 이유가 props만 일차적으로 비교하면 된다고만 나와있었다.. 설명이 부족해 이해가 안 돼서 얘를 붙잡고 쥰내 파보겠다.
꼬꼬무 느낌으로 정리해보겠다.
리액트에서 렌더링을 하면 객체는 주소가 바뀐다.
❓그럼 원시값은
안 바뀐다.
❓왜
원시값는 불변성이니까.
객체는 가변성이라 참조에 의해 비교된다.
리액트는 객체가 바뀌면 새로운 객체로 인식해서 불필요한 렌더링을 한다. (즉, 성능이 떨어짐)
이를 방지하고자 useMemo or React.memo or 불변성유지(기존객체를 복사해 필요한 부분만 변경)를 한다.
여기서 불변성 유지, 기존객체를 복사해 필요한 부분만 변경, 이것이 얕은 복사 얘기다.
리액트는 가상돔을 쓴다.
가상돔: 변경사항(state, props)을 감지해서 변경된 부분만 DOM에 반영하는 식.
여기서 얕은 복사로 변경사항을 감지한다.
// 원본 객체
const originalObject = {
name: 'bomi',
age: 20,
};
// 얕은 복사를 사용하여 객체 복사
const copiedObject = { ...originalObject };
// 복사본 객체 수정
copiedObject.age = 21; // 복사본의 age 속성 변경
console.log(originalObject); // 원본 객체 출력: { name: 'bomi', age: 20 }
console.log(copiedObject); // 복사본 객체 출력: { name: 'bomi', age: 21 }
const [userInfo, setUserInfo] = React.useState({
name: '보미',
age: 20
});
// 객체를 얕은 복사하여 age 속성을 변경
const updateAge = () => {
setUserInfo(prevInfo => ({
...prevInfo,
age: 21
}));
};
얕은 복사 했으니까 일단 두 객체는 다른 주소를 참조함.
객체 주소가 바뀌니까 렌더링이 일어날 것임.
근데 그 과정에서 age속성을 21로 바꿨으니 변화를 감지해서 age만 싸악 변경됨.
...prevInfo -> 얕은 복사하고, 변화면 age만 적용된다.
❓if) props 안에 중첩객체가 있다면
중접객체를 바꾸면 인식을 못한다.
❓왜
얕은 복사를 하게 되면 그 중첩객체는 원래의 객체 주소를 참조하기 때문에(원래 객체의 동일한 주소 참조)
그래서 얘를 방지하고자 useMemo나 useCallback을 씀.
useMemo: 중첩객체가 변경되지 않는 한 이전 값을 재사용함
const [userData, setUserData] = useState({
id: 1,
name: 'bomi',
details: {
age: 20,
city: 'seoul'
}
});
// 중첩된 객체의 속성을 변경하는 함수
const updateDetails = () => {
setUserData(prevUserData => ({
...prevUserData,
details: {
...prevUserData.details,
age: 21 // 나이를 변경
}
}));
};
얕은 복사로 인해 age의 변화를 인식하지 못한다.
const [userData, setUserData] = useState({
id: 1,
name: 'bomi',
details: {
age: 20,
city: 'seoul'
}
});
// 중첩된 객체의 속성을 변경하는 함수
const updateDetails = () => {
setUserData(prevUserData => ({
...prevUserData,
details: {
...prevUserData.details,
age: 21 // 나이를 변경
}
}));
};
const memoizedUserData = useMemo(() => userData, [userData]);
'🔥React 뽀개기' 카테고리의 다른 글
라이브러리 없이 state로 폼 만들기 (0) | 2024.07.31 |
---|---|
스크롤시 투명한 배경에서 배경색 넣기(feat. 화살표 클릭 시 맨 위로 이동하기) (0) | 2024.07.27 |
서버 상태 💞 클라이언트 상태 (0) | 2024.07.20 |
React Query 왜 씀? (1) | 2024.07.20 |
리액트 왜 씀? (0) | 2024.05.27 |