요약
- useCallback / useMemo의 목적
- 함수나 값을 메모이제이션해서 참조 안정성(referential stability) 을 유지하는 것.
- 주된 이유는 두 가지:
- 성능 최적화 (자식 컴포넌트가 React.memo 되어 있을 때, props 참조가 변하지 않게 해서 불필요한 리렌더링 방지)
- useEffect 의 dependency가 불필요하게 자주 변하지 않게 하기 위함
- 쓸모 없는 경우
- 메모제이션 값을 React.memo가 아닌 자식 컴포넌트의 props로 넘겨주는 경우 → useCallback을 써도 아무 성능 효과가 없음. (그냥 불필요한 오버헤드만 늘어남)
- props로 받은 값을 dependency로 그대로 넣는 경우 → 상위 컴포넌트가 매번 새로운 참조를 넘기면 memoization이 깨져서 소용없음. (깨지기 쉬운 구조)
- 실무 사례 (Sentry 코드 예시)
- useHotkeys 훅에서 hotkeys 배열을 dependency로 사용했는데, 상위에서 매번 새로운 배열을 만들면 memoization이 무용지물이 됨.
- 결국 dependency 체인이 길어질수록 유지보수가 어려워짐.
- 해결책
- Latest Ref 패턴: useRef에 최신 값을 저장하고, useCallback은 빈 deps로 두어 항상 안정적인 참조를 제공.
- 내부에서는 ref.current를 참조 → 의존성 관리 문제 해결.
- React의 향후 기능: useEffectEvent (실험적)
- 항상 최신 값을 참조하면서도 안정적인 함수를 제공 → 불필요한 useCallback 사용 줄어듦.
- 결론
- useCallback / useMemo는 남용하지 말 것.
- “참조 안정성이 정말 필요한 상황”에만 사용.
- 앞으로는 useEffectEvent 같은 개선된 기능을 활용하는 게 더 안전하고 직관적일 것.
👉 한 줄 정리:
useCallback은 무조건 쓰는 습관이 오히려 해로울 수 있다. 꼭 필요할 때만 쓰고, 앞으로는 useEffectEvent 같은 새로운 패턴을 쓰는 게 바람직하다.