❓ useMemo
- 계산 비용이 높은 작업의 결과를 메모이제이션하여 동일한 입력값에 대해 반복적으로 계산하지 않도록 한다.
▶ 기본 사용 예시
import React, { useMemo } from 'react';
function ExpensiveCalculationComponent({ num }) {
const result = useMemo(() => {
console.log('Expensive calculation...');
return num * 2;
}, [num]);
return <div>Result: {result}</div>;
}
❓ useCallback
- 함수 자체를 메모이제이션하여 렌더링 시 불필요하게 함수가 재생성되지 않도록 한다. 주로 자식 컴포넌트에 콜백을 전달할 때 사용된다.
▶ 기본 사용 예시
import React, { useCallback } from 'react';
function ParentComponent() {
const [count, setCount] = React.useState(0);
const increment = useCallback(() => {
setCount((prev) => prev + 1);
}, []);
return <ChildComponent onClick={increment} />;
}
function ChildComponent({ onClick }) {
return <button onClick={onClick}>Increment</button>;
}
❗ 사용이유
✅ 성능 최적화
- useMemo는 복잡한 계산을 캐싱하여 불필요한 재계산을 방지
- useCallback은 함수 참조를 캐싱하여 자식 컴포넌트의 불필요한 재렌더링을 방지
✅ 코드 안정성
- 메모이제이션된 값과 함수는 참조 동등성을 유지하므로 의도치 않은 렌더링 문제를 줄일 수 있다.
💥 주의
1️⃣ 과도한 사용
- 굳이 필요하지 않은 곳에 useMemo 또는 useCallback을 사용하는 것은 코드 복잡성을 증가시키고 오히려 성능을 저하시킬 수 있다.
2️⃣ 의존성 배열 관리
- 의존성 배열을 잘못 설정하면 잘못된 결과를 초래하거나 값이 업데이트되지 않을 수 있다.
💠 예시
1️⃣ useMemo로 데이터 필터링 최적화 및 복잡한 계산 결과 캐싱
const filteredData = useMemo(() => {
return data.filter(item => item.active);
}, [data]);
const sortedItems = useMemo(() => {
return items.sort((a, b) => a.value - b.value);
}, [items]);
사용자가 동일한 데이터를 여러 번 요청하거나, 필터링 조건이 변경되지 않는 경우 매우 유용하다.
하지만, useMemo를 사용할 필요가 없는 경우가 있으니 주의해야한다.
예를 들어, 입력값이 매번 바뀌는 함수(재사용성이 없는 경우)와 계산 비용이 낮은 경우(단순 덧셈 등)가 있다.
그러면 언제 useMemo를 사용해야될까?
필터링이나 정렬 작업에서 동일한 데이터를 반복적으로 처리해야 할 때, CPU리소스를 많이 사용하는 작업, 결과 재사용성이 높은 경우에는 useMemo를 사용하는 것이 효과적이다.
2️⃣ useCallback으로 자식 컴포넌트에 콜백 전달
const handleDelete = useCallback((id) => {
deleteItem(id);
}, [deleteItem]);
✅ useMemo / useCallback과 캐싱의 차이점
1️⃣ useMemo / useCallback
- 이전 값을 재사용하지만, 특정 저장소에 미리 저장(캐싱)해두는 방식은 아니다.
- 리액트의 리렌더링 과정에서 메모이제이션된 값을 재사용하는 것이므로, 캐싱보다는 렌더링 최적화에 가깝다.
2️⃣ 캐싱(Cache)
- useMemo와 useCallback은 컴포넌트가 리렌더링될 때마다 메모리를 재할당할 수도 있다.
- 하지만 캐싱은 렌더링과 상관없이 데이터 저장이 유지될 수 있고, 특정 저장소에 데이터를 보존하며 더 장기적인 최적화를 수행한다.
useMemo / useCallback | 캐싱(Cache) | |
목적 | 렌더링 최적화 | 빠른 데이터 재사용 |
저장 위치 | 메모리 (리액트 내부) | 메모리, 로컬 스토리지, DB 등 |
유효 기간 | 의존성이 변경되면 사라짐 | 설정된 정책에 따라 유지 |
활용 사례 | 연산 최적화, 불필요한 리렌더링 방지 | API 응답 저장, 이미지 로딩 속도 개선 |
'React' 카테고리의 다른 글
[React] Fragment (0) | 2025.03.31 |
---|---|
[React] Zustand의 Selector + shallow (0) | 2025.03.30 |
[React] useCallback (0) | 2025.03.27 |
[React-Query]prefetchQuery (0) | 2025.02.25 |
useEffect의 의존성 배열 (0) | 2024.03.10 |