TL;DR: React Compiler owns memoization now. When its eslint rules flag a
useMemo, delete the annotation first — don'teslint-disable. Nine times out of ten, plain code is the fix.
the setup
We were building the L10 view (L10 = Level 10 meeting, the EOS weekly metrics review) for an ecommerce client's supply chain OS app. My client had asked for a "Sold (last 30 days)" bar chart at the bottom — one bar per SKU, sized relative to the top seller.
I built it. Fast.
And like pure reflex, I wrapped the max-value calculation in useMemo:
const maxSold = useMemo(
() => Math.max(...sold30dBars.map(b => b.value)),
[sold30dBars]
)
I've written that exact pattern a thousand times.
the complaint
React Compiler did not like it.
Not a warning — a hard error.
eslint-config-next 16 ships the new react-hooks plugin (v6) with rules that fire as errors, not warnings. Older configs never even flagged these. A fresh eslint . could have 10+ new errors on a codebase that built clean all week — that's exactly what's happening here.
I'll be honest: I don't know the precise reason the compiler objected to this specific useMemo. The commit just says "React Compiler complaint." What I do know is the wrong move is eslint-disable.
I've internalized that hard. These rules exist for real reasons. The React Compiler is designed to own memoization — and when you manually annotate, you're potentially stepping on what it's trying to do. The rule exists because that tension is real.
the fix
One line deleted.
const maxSold = Math.max(...sold30dBars.map(b => b.value))
Plain JavaScript. No annotation, no dependency array, no wrapper.
The error went away. The bars rendered. The L10 feature shipped.
why it matters
Here's the shift I'm still internalizing: with the React Compiler in the picture, your job isn't to annotate what to memoize.
Your job is to write clean, pure code and let the compiler figure out the rest.
That means when you see a React Compiler error on a useMemo… your first instinct should be delete, not fix the array. Not eslint-disable. Delete.
I've been reaching for useMemo by reflex for years — and most of those calls are probably fine, or at least harmless. But this was a useful reminder: we're in new territory with React 19. The tooling is actively telling us something has changed about who owns optimization.
I'm paying attention to that now. The reflex is starting to fade.