부모와 자식 컴포넌트 간의 렌더링 최적화와 계산 최적화가 어떻게 작동하는지 실험해보려고 한다.
부모 컴포넌트가 리렌더링될 때 자식 컴포넌트가 리렌더링 되는지 확인하고 useMemo와 React.memo가 각각 최적화에 어떻게 작동하는지 알아보자.
🧩 예제 코드
- ParentWithMemo
- input과 count 상태를 관리
- input 값으로 무거운 계산 실행
- 계산 결과(calculatedValue)를 자식 컴포넌트에 넘긴다
import { useMemo, useState } from 'react';
import MemoizedChild from './MemoizedChild';
const heavyCalculation = (num: number) => {
console.log('💥 무거운 계산 실행');
let result = 0;
for (let i = 0; i < 100000000; i++) {
result += i * num;
}
return result;
};
const ParentWithMemo = () => {
const [input, setInput] = useState(1);
const [count, setCount] = useState(0);
// ❌ 캐싱하지 않음
// const calculatedValue = heavyCalculation(input);
// ✅ 무거운 계산 결과 캐싱
const calculatedValue = useMemo(() => heavyCalculation(input), [input]);
return (
<div style={{ padding: 20 }}>
<h2>useMemo + React.memo 조합 실험</h2>
<input type="number" value={input} onChange={e => setInput(Number(e.target.value))} />
<button onClick={() => setCount(c => c + 1)}>count: {count}</button>
<MemoizedChild value={calculatedValue} />
</div>
);
};
export default ParentWithMemo;
- MemoizedChild
- props로 받은 값 출력
- React.memo로 감싸서 props 변경이 없으면 리렌더링 방지
const MemoizedChild = memo(({ value }: { value: number }) => {
console.log('🧒 자식 컴포넌트 렌더링');
return <div>자식이 받은 값: {value}</div>;
});
🧮 실험 과정
1️⃣ useMemo로 무거운 계산 캐싱
const calculatedValue = useMemo(() => heavyCalculation(input), [input]);
- input이 바뀌면 → 무거운 계산 실행
- input이 안 바뀌면 → 이전 계산값 재사용
2️⃣ 부모 리렌더링 시 자식 리렌더링 여부 확인
<MemoizedChild value={calculatedValue} />
- input 값 변경 → props 변화 → 자식 렌더링 ✅
- count 값 변경 → props 동일 → 자식 렌더링 ❌
✏️ 정리
역할 | 최적화 대상 |
useMemo | 부모 컴포넌트의 계산 최적화 |
React.memo | 자식 컴포넌트의 렌더링 최적화 |
부모 상태(state)가 바뀌면 무조건 부모는 리렌더링된다
- count를 변경하면 ParentWithMemo는 항상 리렌더링된다
자식은 props가 바뀌지 않으면 리렌더링되지 않는다
- React.memo가 props가 같으면 리렌더링을 막아준다
- 부모 리렌더링 → props 비교 → 같으면 자식 렌더링 스킵
useMemo는 계산 최적화를 해준다 (props 최적화는 아님)
- useMemo는 값을 캐싱해서 무거운 계산을 줄여준다
- 하지만 자식 리렌더링 여부는 props가 같냐 다르냐로 결정된다
primitive 값(숫자, 문자열)은 참조 비교와 값 비교가 같다
- React.memo를 사용했을 때, useMemo가 없어도 값이 같으면 자식은 리렌더링되지 않는다
- 만약 props가 객체나 배열이면 매번 참조가 바뀌어 리렌더링된다
객체나 배열을 props로 넘기면 매번 참조가 바뀌므로 리렌더링된다
- 이런 경우 useMemo 또는 useCallback으로 참조를 유지해야 한다
반응형
'Library & Runtime > React' 카테고리의 다른 글
[React] Compound Component 패턴 + Context 이해하기 (0) | 2025.05.06 |
---|---|
[React] Virtual Scroll(가상 스크롤)로 렌더링 최적화하기 (react-window) (0) | 2025.05.05 |
[React] 무거운 연산 최적화 : 일반 계산 vs useMemo (0) | 2025.05.03 |
[React] 자식 컴포넌트 렌더링 : 일반 함수 vs useCallback (0) | 2025.05.02 |