React 19 RC: The Compiler Retires useMemo
React 19 hit RC this month, and its theme is deletion: whole categories of code we've written for years — memoization boilerplate, form-state plumbing, forwardRef ceremony — become unnecessary. A tour of what you get to remove.
The compiler ends the memoization era
React Compiler (now powering instagram.com) analyzes your components and auto-memoizes at build time. This code:
const filtered = useMemo(
() => products.filter((p) => p.category === category),
[products, category]
);
const handleSelect = useCallback((id) => onSelect(id), [onSelect]);
becomes this code:
const filtered = products.filter((p) => p.category === category);
const handleSelect = (id) => onSelect(id);
The compiler inserts equivalent (usually better) memoization automatically — it never forgets a dependency and never misses one. The years of useCallback-or-not code review debates just... end. It requires following the Rules of React (the ESLint plugin verifies), and it's opt-in for now, but this is clearly the future default.
Actions and useActionState
Async transitions get first-class form support:
const [state, submitAction, isPending] = useActionState(
async (prev, formData) => {
const err = await updateProfile(formData);
return err ?? { ok: true };
},
null
);
<form action={submitAction}>
<input name="displayName" />
<button disabled={isPending}>Save</button>
{state?.error && <p role="alert">{state.error}</p>}
</form>
Pending state, error state, and optimistic updates (useOptimistic) — the plumbing every form hand-rolls, now built in, and shared with the Server Actions model.
Small deletions that add up
use(promise) reads promises in render (with Suspense integration) and — unlike hooks — works conditionally. ref is now a regular prop: every forwardRef wrapper in your design system can be unwrapped. <Context> renders as a provider directly. Document metadata (<title>, <meta>) hoists automatically from any component.
Migration reality: 19 itself is a mild upgrade (codemods cover the breaking changes), and the compiler can be adopted incrementally, file by file. Start with the ESLint plugin today — it flags the rule violations you'd need to fix anyway, and your future self will merge the compiler PR with a grin.