--- id: react-usememo-when-not-to title: useMemo 를 쓰지 말아야 할 때 category: Coding status: draft source_trust_level: B verification_status: conceptual created_at: 2026-05-09 updated_at: 2026-05-09 tags: [react, hooks, useMemo, performance, vibe-coding] tech_stack: { language: "TypeScript / React 18+", applicable_to: ["Web", "React Native"] } applied_in: [] aliases: [memoization, premature optimization, reference equality] --- # useMemo 를 쓰지 말아야 할 때 > useMemo 는 무료가 아니다. 의존성 비교 + 클로저 유지 비용. **참조 동일성이 진짜 필요할 때만** 또는 **계산이 진짜 비싼 경우만** 쓴다. ## 📖 핵심 개념 useMemo 는 두 가지 목적: 1. **참조 동일성 보장**: 자식의 useEffect/useMemo deps 또는 React.memo 비교에 사용 2. **고비용 계산 캐시**: 매 렌더 다시 계산 안 함 이 둘이 아니면 useMemo 는 오히려 메모리 + 비교 비용만 추가. ## 💻 코드 패턴 ```ts // ✅ 자식 useEffect deps 안정화 const config = useMemo(() => ({ id, mode }), [id, mode]); useChildHook(config); // config 가 매 렌더 새 객체면 자식 effect 무한 trigger // ✅ 진짜 비싼 계산 const sorted = useMemo(() => bigArray.slice().sort(cmp), [bigArray]); // ❌ 단순 변환 — useMemo 비용이 더 큼 const upper = useMemo(() => name.toUpperCase(), [name]); ``` ## 🤔 의사결정 기준 | 상황 | useMemo | |---|---| | 자식 props 가 객체/배열, React.memo 적용 자식 | ✅ | | 자식의 useEffect deps 로 들어감 | ✅ | | 정렬·필터 등 O(n log n) 이상 계산, n>1000 | ✅ | | 단순 string 변환, 산술 | ❌ (useMemo 비용 > 계산 비용) | | 이미 useState 의 setState lazy init 으로 충분 | ❌ | ## ❌ 안티패턴 - **모든 계산에 useMemo**: cargo cult. 99% 의 useMemo 는 이득 < 비용. - **deps 에 객체 리터럴**: `useMemo(() => foo(opts), [{ a: 1 }])` — 매번 새 객체, 영원히 미스. - **side effect in factory**: useMemo 는 pure 가정. fetch / setState 넣으면 React 가 임의 실행 가능. - **React.memo 없이 props 안정화만 위해 useMemo**: 자식이 memoized 안 되면 의미 없음. - **실측 안 한 최적화**: Profiler 로 측정 후 결정. ## 🤖 LLM 활용 힌트 - "useMemo 는 (a) React.memo 자식 props 안정화 또는 (b) 측정된 비싼 계산만" 명시. - LLM이 unnecessary useMemo 추가하면 제거 요청. ## 🔗 관련 문서 - [[React_useCallback_Reality]] - [[React_Rendering_Optimization]]