--- title: "useMemo, 컴파일러에 맡겨도 될까" description: "React Compiler 1.0이 실제로 만드는 코드를 열어 보고, 조용히 건너뛰는 컴포넌트와 잡지 못하는 버그를 확인한 기록" date: 2025-10-13 updated: 2026-09-28T04:12:00.000Z tags: [React, Next.js] source: https://crowrish.com/blog/usememo-react-compiler site: "CrowRish Blog" --- > 2025년 10월에 쓴 글을 2026년 9월에 다시 썼습니다. 2025년 10월, Next.js 16 베타가 나온 직후에 이 주제로 글을 썼습니다. 다시 읽어 보니 발표 자료를 옮겨 적은 수준이었습니다. 컴파일러가 "알아서 최적화해 준다"고 써 놓고, 정작 컴파일러가 뭘 만드는지는 한 번도 열어 보지 않았습니다. 그래서 이번엔 직접 돌려 봤습니다. `babel-plugin-react-compiler` 1.0으로 예제 컴포넌트와 이 블로그 코드를 컴파일하고, 결과를 보면서 원래 질문에 다시 답해 봤습니다. ## 처음 질문 ```typescript function ProductList({ products, onSelect }) { const filtered = products.filter((p) => p.inStock); return (
{total} ({renders.current})
; } ``` 결과는 원본 그대로였습니다. `_c`도 없고 캐시 칸도 없습니다. 컴파일러 로그를 켜야 이유가 보입니다. ```plain text CompileError: Cannot access refs during render ``` 빌드는 멀쩡히 성공합니다. 컴파일러는 확신할 수 없는 컴포넌트를 에러로 멈추지 않고, **그 컴포넌트만 최적화하지 않고 넘어갑니다.** "컴파일러 켰으니 다 됐겠지" 하고 넘어가면, 정작 느린 컴포넌트가 이런 식으로 빠져 있어도 모릅니다. 기존 `useMemo`가 오히려 발목을 잡는 경우도 있었습니다. ```typescript function Total({ items }) { const total = useMemo(() => items.reduce((s, i) => s + i.price, 0), []); return{total}
; } ``` 의존성 배열에 `items`를 빼먹은 코드입니다. 컴파일러는 이걸 고쳐 주지 않고, 컴포넌트 전체를 포기합니다. ```plain text CompileError: Existing memoization could not be preserved The inferred dependency was `items`, but the source dependencies were []. ``` 손으로 쓴 메모이제이션을 함부로 바꾸면 동작이 달라질 수 있으니, 맞지 않으면 아예 손대지 않습니다. 틀린 의존성 배열이 있던 컴포넌트는 컴파일러를 켜도 이득이 없습니다. 이런 걸 빌드 로그 대신 에디터에서 보려면 `eslint-plugin-react-hooks` 최신 버전을 쓰면 됩니다. 1.0 발표에서 컴파일러와 같은 규칙으로 검사하는 린트를 이 플러그인에 합쳤다고 합니다. ## 잡지 못한 버그 예전 글에는 컴파일러가 "Rules of React를 검증해서 숨어 있던 버그까지 찾아 준다"고 썼습니다. 이것도 확인해 봤습니다. ```typescript function ProductList({ products }) { const sorted = products.sort((a, b) => a.price - b.price); return