useMemo와 useCallback은 언제 사용해야 하나요?
답변 포인트
계산 비용과 참조 동일성를 기준으로 정의, 장점, 한계, 예시를 함께 설명해보세요.
정답 및 해설
빠른 요약
useMemo는 비싼 계산 결과를, useCallback은 함수 참조를 메모이제이션합니다. memoized child나 의존성 배열에서 참조 안정성이 실제 문제가 될 때 선택적으로 사용하는 것이 좋습니다.
useMemo는 비싼 계산 결과를, useCallback은 함수 참조를 메모이제이션합니다. memoized child나 의존성 배열에서 참조 안정성이 실제 문제가 될 때 선택적으로 사용하는 것이 좋습니다.
핵심 개념
핵심 기준은 계산 비용과 참조 동일성입니다. 이 개념은 단순한 용어가 아니라, 실제 코드나 시스템에서 반복적으로 생기는 문제를 다루기 위해 등장했습니다.
React에서는 상태 변화가 렌더링으로 이어지는 흐름을 예측 가능하게 만드는 것이 중요합니다. 컴포넌트 경계와 렌더링 비용을 이해하면 더 부드러운 UI를 만들 수 있습니다.
동작 흐름
- 먼저 어떤 문제가 있는지 확인합니다.
- 이 개념이 그 문제를 어떤 기준으로 나누거나 해결하는지 봅니다.
- 실제 코드에서는 입력, 상태, 실행 순서, 비용이 어떻게 바뀌는지 확인합니다.
- 마지막으로 한계와 부작용을 함께 점검합니다.
실제 예시
const visibleItems = useMemo(() => {
return items.filter((item) => item.name.includes(keyword));
}, [items, keyword]);
const handleSelect = useCallback((id: string) => {
setSelectedId(id);
}, []);계산 비용이나 참조 동일성이 실제 문제가 되는 곳에 제한적으로 쓰는 것이 좋습니다.
실무에서 주의할 점
- 상태를 너무 위로 올리면 불필요한 렌더링 범위가 커집니다.
- memoization은 병목이 확인된 곳에 쓰는 편이 좋습니다.
- 사용자 입력, 로딩, 에러 상태를 함께 설계해야 실제 화면이 안정적입니다.
함께 연결해서 보면 좋은 키워드
React, useMemo, useCallback, 성능
정리
한 줄로 정리하면, useMemo는 비싼 계산 결과를, useCallback은 함수 참조를 메모이제이션합니다. memoized child나 의존성 배열에서 참조 안정성이 실제 문제가 될 때 선택적으로 사용하는 것이 좋습니다. 실무에서는 개념을 적용하는 조건과 적용하지 않았을 때 생기는 문제까지 함께 이해하는 것이 중요합니다.
useMemo와 useCallback의 목적
useMemo는 계산 결과를 메모이제이션하고, useCallback은 함수 참조를 메모이제이션합니다. 둘 다 “항상 빠르게 만드는 도구”가 아니라, 참조 안정성이 필요하거나 계산 비용이 큰 경우에 사용합니다.
const filtered = useMemo(() => {
return items.filter((item) => item.name.includes(keyword));
}, [items, keyword]);
const handleSelect = useCallback((id: string) => {
setSelectedId(id);
}, []);사용할 만한 경우
- 큰 배열 필터링/정렬처럼 비용이 큰 계산
React.memo로 감싼 자식에게 안정적인 props를 넘길 때- hook dependency로 함수 참조 안정성이 필요할 때
남용하면 생기는 문제
메모이제이션 자체도 dependency 비교와 메모리 비용이 있습니다. 계산이 가볍거나 리렌더가 병목이 아니라면 오히려 코드만 복잡해집니다. 먼저 Profiler로 병목을 확인하는 습관이 좋습니다.