들어가며
React 애플리케이션에서 불필요한 리렌더링은 성능 저하의 주요 원인입니다. React.memo는 이러한 문제를 해결할 수 있는 강력한 도구지만, 무분별한 사용은 오히려 성능을 저하시킬 수 있습니다. 언제, 어떻게 React.memo를 사용해야 할지 알아보겠습니다.
React.memo가 필요한 이유
// 부모 컴포넌트가 리렌더링될 때마다 자식 컴포넌트도 불필요하게 리렌더링됩니다
const ParentComponent = () => {
const [count, setCount] = useState(0);
return (
<div>
<button onClick={() => setCount(count + 1)}>
Count: {count}
</button>
<ExpensiveChild data="이 데이터는 변하지 않습니다" />
</div>
);
};
React.memo 기본 사용법
1. 간단한 사용 예시
const ExpensiveChild = React.memo(function ExpensiveChild({ data }) {
return <div>{data}</div>;
});
2. 커스텀 비교 함수 사용
const MyComponent = React.memo(function MyComponent({ data }) {
return <div>{data.value}</div>;
}, (prevProps, nextProps) => {
return prevProps.data.value === nextProps.data.value;
});
React.memo를 사용해야 하는 경우
1. 순수 표현 컴포넌트
// Good: props가 자주 변경되지 않는 경우
const UserProfile = React.memo(function UserProfile({ name, avatar }) {
return (
<div>
<img src={avatar} alt={name} />
<h2>{name}</h2>
</div>
);
});
2. 비용이 큰 렌더링
// Good: 복잡한 계산이나 큰 리스트를 렌더링하는 경우
const ExpensiveList = React.memo(function ExpensiveList({ items }) {
return (
<div>
{items.map(item => (
<ComplexItem key={item.id} {...item} />
))}
</div>
);
});
React.memo를 피해야 하는 경우
1. 자주 변경되는 props
// Bad: props가 매번 변경되는 경우
const Counter = React.memo(function Counter({ count, onClick }) {
return <button onClick={onClick}>{count}</button>;
});
// Parent
function Parent() {
const [count, setCount] = useState(0);
// 이 함수는 매 렌더링마다 새로 생성됩니다
const handleClick = () => setCount(count + 1);
return <Counter count={count} onClick={handleClick} />;
}
2. 단순한 컴포넌트
// Bad: 렌더링 비용이 메모이제이션 비용보다 적은 경우
const TooSimple = React.memo(function TooSimple({ text }) {
return <span>{text}</span>;
});
최적화 팁
1. useCallback과 함께 사용하기
function Parent() {
const [count, setCount] = useState(0);
const handleClick = useCallback(() => {
setCount(c => c + 1);
}, []); // 의존성 배열이 비어있으므로 함수가 재생성되지 않습니다
return <Counter count={count} onClick={handleClick} />;
}
2. useMemo로 객체 props 최적화
function Parent() {
const data = useMemo(() => ({
title: "제목",
description: "설명"
}), []); // 객체가 재생성되지 않습니다
return <ComplexComponent data={data} />;
}
성능 측정하기
React DevTools 사용
// 개발 모드에서만 실행
if (process.env.NODE_ENV === 'development') {
const whyDidYouRender = require('@welldone-software/why-did-you-render');
whyDidYouRender(React);
}
실제 측정 예시
const MeasuredComponent = React.memo(function MeasuredComponent({ data }) {
console.time('render');
// 렌더링 로직
console.timeEnd('render');
return <div>{/* 컴포넌트 내용 */}</div>;
});
체크리스트
React.memo 사용 전 확인사항:
- 컴포넌트가 같은 props로 자주 렌더링되는가?
- 컴포넌트의 렌더링 비용이 큰가?
- 컴포넌트의 props가 자주 변경되지 않는가?
- 부모 컴포넌트가 자주 리렌더링되는가?
마무리
React.memo는 강력한 도구지만, 모든 상황에서 사용하는 것은 오히려 역효과를 낼 수 있습니다.
컴포넌트의 특성과 실제 성능 측정을 통해 필요한 곳에만 적절히 사용하는 것이 중요합니다.
'React.js' 카테고리의 다른 글
[React 19] useActionState로 서버 상태 관리하기 (0) | 2025.03.17 |
---|---|
[React 19] useTransition으로 더 부드러운 UI 구현하기 (0) | 2025.03.17 |
[React] 웹 페이지 복귀, 이탈 탐지 (가시성) (0) | 2023.06.28 |
React 앱을 Vite + gh-pages로 빌드 및 배포하기 (0) | 2023.06.17 |
[React] ReferenceError: Buffer is not defined (0) | 2023.06.15 |