React 19: ref is a prop
Drop forwardRef, and read context with use(), even conditionally.
React docsreact.dev
Unlike React Hooks, use can be called within loops and conditional statements like if.
From vercel-composition-patterns, rule react19-no-forwardref.
Fewer wrappers, real names
Wrap it in memo, then focus each input through its ref.
forwardRefBad
1 tree nodesname: ForwardRef
forwardRef<TextInput, Props>((props, ref) => …)ref as a propGood
1 tree nodesname: ComposerInput
function ComposerInput({ ref, ...props })function ComposerInput({ ref, ...props }: Props & { ref?: React.Ref<TextInput> }) {
return <TextInput ref={ref} {...props} />
}
use() after an early return
Collapse both, then change the theme a few times.
useContext at the topBad
Details1 renders0 renders while collapsed
hooks can't follow an early returnuse() after the returnGood
Details1 renders0 renders while collapsed
no read, no subscriptionfunction Details({ open }: { open: boolean }) {
if (!open) return null
const theme = use(ThemeContext) // fine after an early return
return <section className={theme}>…</section>
}
Why it matters, pros and cons
Why it matters
React 19 passes ref like any prop, so the wrapper only costs a name and a layer. use() can sit behind a condition.
Pros
- No wrapper, no
displayName, plain props type. - Components keep their own name in DevTools.
- Context read only on the paths that need it.
Cons
- React 19+ only; libraries on 18 still need
forwardRef. - Class components still can't take
refas a prop. - Mixed codebases carry both styles for a while.