가상 DOM과 부분 렌더링 방식이해
가상 DOM의 작동 방식
- 가상 DOM 생성: 브라우저의 실제 DOM과 별개로 메모리에 가상 DOM 객체를 생성합니다.
- 상태 변화 감지: 데이터나 상태가 변경되면, 새로운 가상 DOM 트리가 생성됩니다.
- 차이점 계산(Diffing): 기존 가상 DOM과 새 가상 DOM을 비교하여 정확히 어떤 부분이 변경되었는지 파악합니다.
- 부분 업데이트(Reconciliation): 변경된 부분만 실제 DOM에 적용합니다.
랜더링 최적화의 필요성
상태가 변경됨에 따라 컴포넌트가 재렌더링되는 과정에서 하위 컴포넌트 역시 재렌더링 되어 일부 불필요한 렌더링이 발생할 수 있습니다.
예를 들어 Context API 의 Context 및 state 값이 변경되면, 해당 컴포넌트의 모든 자식 컴포넌트들도 기본적으로 재렌더링 과정을 거치게 됩니다.
React.memo
- 컴포넌트의 불필요한 재렌더링 방지
- props가 변경되지 않으면 해당 컴포넌트는 재렌더링하지 않습니다.
- 자식 컴포넌트가 불필요하게 재렌더링되는 문제를 해결
// ✅ 올바른 사용법 1: 컴포넌트를 React.memo로 감싸는 방식
fuction MyComponent() {
...
}
or
const MyComponent = () => {
...
}
const MemoizedComponent = React.memo(MyComponent);
// ✅ 올바른 사용법 2: 화살표 함수와 React.memo를 함께 사용하는 방식
const MyComponent = React.memo(() => {
...
})
// ❌ 잘못된 사용법: 함수 선언문 안에서 React.memo 사용
React.memo(fuction MyComponent() {
...
})
useMemo
- 값의 계산을 메모이제이션하여 불필요한 계산을 방지합니다.
- 의존성 배열이 변경되지 않으면 동일한 값을 반환하여 성능을 최적화합니다.
const [name, setName] = useState('Kim');
const [age, setAge] = useState(30);
// name과 age가 변경될 때만 새 객체 생성
const userInfo = useMemo(() => {
return { name, age, formattedAge: `${age}세` };
}, [name, age]);
useCallback
- 컴포넌트 안에서 선언되는 함수는 재랜더링되는 과정에서 새로 선언되기 때문에 함수의 메모이제이션을 통해 불필요한 함수 재생성을 방지합니다.
useMemo
와 유사하지만, 함수에 특화된 메모이제이션입니다.
import { useCallback, useState } from "react";
export default fuction useSwitch(defaultState: boolean): [boolean, () => void, () => void] => {
const [isOn, setCurrentState] = useState(defaultState ?? false);
const turnOn = useCallback(() => setCurrentState(true), []);
const turnOff = useCallback(() => setCurrentState(false), []);
return [isOn, turnOn, turnOff];
};
그외 알아두면 좋을만한 것
- useState에서 setState는 React가 내부적으로 관리하는 함수이기 때문에, 함수 참조가 항상 동일하고, 리렌더링 시 상태 업데이트 함수 자체가 변경되지 않기 때문에 memoization을 고려할 필요가 없다 예를 들어 useCallback에서 setState를 사용한다고 해서 의존성 배열에 추가할 필요가 없다.
- props 에 익명함수의 형태로 바로 전달할 경우 리렌더링 시마다 익명 함수가 새로 생성되므로, 리렌더링이 일어날 때마다 자식 컴포넌트의 리렌더링도 발생할 수 있습니다.
- 배열이나 객체는 참조형 데이터이므로, 그 자체로 useState로 상태를 관리하면 참조가 유지됩니다. 따라서 해당 값이 변경되지 않는 한, 해당 참조를 사용하는 props로 전달되는 값은 불변입니다. 따라서 props 로 전달할 때 참조가 새로 적용되어 재렌더링되는 것을 걱정할 필요는 없다
- children 역시 props의 일종으로 React.memo는 props가 변경되지 않으면 해당 컴포넌트의 리렌더링을 방지합니다. 이때 children이 변경되지 않으면, 해당 엘리먼트의 참조는 유지되고 리렌더링을 피할 수 있습니다.
'React' 카테고리의 다른 글
react-router v7 Framework Mode 라우트 방식 (0) | 2025.03.30 |
---|---|
React Hook Form 이해 (0) | 2024.11.02 |
[React] 지나친 추상화 및 파일 분리 시 주의점 (0) | 2024.11.02 |
[React 18. 2] 공식 문서 훑으면서 몰랐던 부분 찾아보기 (0) | 2024.01.04 |
React 에서 이벤트 위임 하지 않는 이유 (0) | 2023.12.22 |