티스토리 뷰
React로 개발하다 보면 성능 최적화를 위해 useMemo와 useCallback을 사용하게 되는데,
두 훅을 언제 어떻게 사용해야 하는지 정리해보자
useMemo
연산 결과 값을 메모이제이션
const expensiveValue = useMemo(() => {
return heavyCalculation(data);
}, [data]);
useCallback
함수 자체를 메모이제이션
const handleClick = useCallback(() => {
doSomething(id);
}, [id]);
언제 사용해야 할까?
1. 자식 컴포넌트에 props로 전달되는 함수
// 안 좋은 예
// Parent가 리렌더링될 때마다 handleClick은 새로운 참조를 가진 함수가 됨
// memo로 감싸져 있지만 props인 onClick이 매번 바뀌어 불필요하게 리렌더링 됨
function Parent() {
const [count, setCount] = useState(0);
const handleClick = () => {
console.log('clicked');
};
return <ChildComponent onClick={handleClick} />;
}
const ChildComponent = memo(({ onClick }) => {
console.log('Child rendered');
return <button onClick={onClick}>Click</button>;
});
// 좋은 예
// 의존성이 없으므로 한 번만 생성됨
function Parent() {
const [count, setCount] = useState(0);
const handleClick = useCallback(() => {
console.log('clicked');
}, []);
return <ChildComponent onClick={handleClick} />;
}
2. 무거운 연산 결과 캐싱
function ProductList({ products, filter }) {
// filter가 바뀌지 않으면 재계산하지 않음
const filteredProducts = useMemo(() => {
return products
.filter(p => p.category === filter)
.sort((a, b) => b.price - a.price);
}, [products, filter]);
return (
<div>
{filteredProducts.map(product => (
<ProductCard key={product.id} product={product} />
))}
</div>
);
}
3. 의존성 배열에 들어가는 객체/배열
function SearchComponent() {
const [query, setQuery] = useState('');
// 안좋은 예
// 매 렌더링마다 새 객체 생성
// searchOptions가 계속 바뀌어서 무한 루프됨
const searchOptions = {
limit: 10,
offset: 0
};
useEffect(() => {
fetchResults(query, searchOptions);
}, [query, searchOptions]);
// 좋은 예
// 객체를 메모이제이션
const searchOptions = useMemo(() => ({
limit: 10,
offset: 0
}), []);
useEffect(() => {
fetchResults(query, searchOptions);
}, [query, searchOptions]);
}
언제 사용하지 말아야 할까?
1. 단순한 연산
// 안좋은 예
const doubled = useMemo(() => count * 2, [count]);
// 좋은 예
const doubled = count * 2;
2. 자식에게 전달되지 않는 함수
// 안좋은 예
function MyComponent() {
const handleClick = useCallback(() => {
console.log('clicked');
}, []);
return <button onClick={handleClick}>Click</button>;
}
// 좋은 예
function MyComponent() {
const handleClick = () => {
console.log('clicked');
};
return <button onClick={handleClick}>Click</button>;
}'Frontend' 카테고리의 다른 글
| Nuxt3 - 운영 환경에서 console.log 제거하기 (0) | 2026.03.26 |
|---|---|
| CSS Layout 정리 (0) | 2026.02.23 |
| Vue3, Nuxt3 - Suspense (0) | 2026.02.06 |
| Vue3, Nuxt3 - Image Lazy Loading (0) | 2026.02.06 |
| Vue3 - vue3-virtual-scroller (0) | 2026.02.03 |