--- id: frontend-react-compiler-deep title: React Compiler — 자동 memoization deep category: Coding status: draft source_trust_level: B verification_status: conceptual created_at: 2026-05-09 updated_at: 2026-05-09 tags: [frontend, react, compiler, vibe-coding] tech_stack: { language: "TS / React", applicable_to: ["Frontend"] } applied_in: [] aliases: [React Compiler, React Forget, automatic memoization, ESLint react-compiler, useMemoCache] --- # React Compiler Deep > React 19 의 stable feature. **Compiler 가 useMemo / useCallback / React.memo 자동**. 사용자 가 plain code, compiler 가 optimize. ## 📖 핵심 개념 - Babel plugin 가 transform. - 매 component 의 hook 자동 추가. - Rules of React 가 baseline. - ESLint plugin 가 violation 감지. ## 💻 코드 패턴 ### 옛 (manual) ```tsx const sorted = useMemo(() => items.sort(), [items]); const onClick = useCallback((id) => handle(id), [handle]); const Item = React.memo(({ item }: ItemProps) => { return
{item.name}
; }); ``` ### 새 (compiler) ```tsx // 그냥 plain. const sorted = items.sort(); const onClick = (id) => handle(id); const Item = ({ item }: ItemProps) => { return
{item.name}
; }; // Compiler 가 자동 memoize. ``` ### Setup (Vite) ```ts import reactCompiler from 'babel-plugin-react-compiler'; export default { plugins: [ react({ babel: { plugins: [['babel-plugin-react-compiler', { target: '19' }]] }, }), ], }; ``` ### Setup (Next.js 15+) ```js // next.config.js module.exports = { experimental: { reactCompiler: true, }, }; ``` ### ESLint ```bash yarn add -D eslint-plugin-react-compiler # .eslintrc.json { "plugins": ["react-compiler"], "rules": { "react-compiler/react-compiler": "error" } } ``` → Violation 가 compile 못 함. ### Output (compiled) ```tsx // Input function Counter({ count, onIncrement }) { return ; } // Output (대략) function Counter(props) { const $ = _c(2); let t0; if ($[0] !== props.count || $[1] !== props.onIncrement) { t0 = ; $[0] = props.count; $[1] = props.onIncrement; $[2] = t0; } else { t0 = $[2]; } return t0; } ``` → `_c` = useMemoCache (자동 cache). ### Rules of React (compile baseline) ```ts // ❌ Component 안 mutation 외부 let counter = 0; function Counter() { counter++; // 외부 mutation return
{counter}
; } // ✅ State / ref 사용 function Counter() { const [count, setCount] = useState(0); return
{count}
; } ``` ### Mutation 안 됨 ```ts // ❌ Props mutation function Item({ item }) { item.name = item.name.toUpperCase(); // mutation return
{item.name}
; } // ✅ 새 object function Item({ item }) { const upper = item.name.toUpperCase(); return
{upper}
; } ``` ### Effect dependency ```tsx // Compiler 가 useEffect 도 optimize. useEffect(() => { doSomething(value); }, [value]); // → 자동 dependency tracking (compiler 가 보장). ``` → Linter 가 dep 체크 가 unnecessary 가 됨. ### useMemo / useCallback 가 obsolete? ``` 대부분: yes. - Compiler 가 자동. - 더 정확. 남은 use case: - Manual fine-grained control. - Compiler 옵트아웃 file. - 매우 expensive computation (compiler 가 보장 X). ``` ### React.memo 가 obsolete? ``` 대부분: yes. - Compiler 가 component 자동 memo. 남은: - 외부 lib component (compiler 가 못 보는). - 정밀 prop comparison. ``` ### "use no memo" (옵트아웃) ```tsx 'use no memo'; function Component() { // Compiler 가 optimize X. } ``` → 안 optimize 의 file. ### Performance gain ``` Real-world: - 10-30% 빠름 (개발자 실수 fix). - 큰 list = 더 큰. - 작은 component = 작은. → "Manual perfect 한 코드" = gain 0. "Manual 부족 한 코드" = 큰 gain. ``` ### Side effect detection ```tsx function Component() { // ❌ Render 중 side effect localStorage.setItem('x', 'y'); return
; } // → Compiler 가 거부. // ✅ useEffect(() => { localStorage.setItem('x', 'y'); }, []); ``` ### Conditional hook (안 됨) ```tsx // ❌ if (cond) { useState(0); // hook 가 conditional } // ✅ const [x, setX] = useState(cond ? 0 : null); ``` ### Closure stale (자동 fix) ```tsx // 옛 (stale) function Component({ value }) { const onClick = useCallback(() => log(value), []); // dep 빠짐 = stale return