All topics
Advancedintermediate

Refs Forwarding Through Component Layers

Learn how forwardRef enables passing a ref through an intermediate wrapper component to an inner DOM element or component.

By default, function components don't accept a ref prop the way DOM elements do — attempting to pass one to a plain function component produces a console warning, since React needs an explicit signal about where that ref should actually attach inside the component's own internal structure. forwardRef provides that explicit signal, letting a wrapper component receive a ref from its own parent and forward it down to a specific DOM node (or another forwardRef-wrapped component) inside its own render.

Ref forwarding is like a relay handoff where a baton (the ref) passed by a spectator at the start of the race (the top-level parent) gets explicitly handed off runner to runner (each forwardRef layer) until it reaches the final runner (the actual DOM element) at the finish line, rather than getting lost with whichever intermediate runner happened to be holding it.

Key Concepts

1
This matters for any reusable wrapper component — a styled Input wrapping a native <input>, a Button wrapping a native <button> — where a consumer might reasonably want direct access to the underlying DOM element (for focusing, measuring, or integrating with non-React code) exactly as if they'd rendered the native element themselves, without needing to know or care about the wrapper's internal structure.
Input<input>Button<button>
2
Ref forwarding can be chained through multiple layers: a component that itself uses a forwardRef-wrapped child can accept its own ref prop and forward it further down, letting a ref set several component layers up in a design system ultimately reach the actual native DOM element at the bottom, as long as every intermediate layer explicitly forwards it along.
forwardRefref
3
Interviewers ask candidates to add ref forwarding to a wrapped Input component so a parent can call .focus() on it directly, testing whether they correctly use forwardRef and attach the forwarded ref to the actual native element inside, rather than to some other, less useful internal DOM node.
.focus()forwardRef