What Is forwardRef in React and When Do You Need It?
Learn what forwardRef does in React, why refs are dropped without it, and how it pairs with useImperativeHandle.
Expected Interview Answer
forwardRef is a React API that lets a component receive a ref passed to it by a parent and forward that ref down to one of its own inner DOM nodes or child components, which is necessary because refs aren’t passed as a regular prop and are ignored by function components by default.
Normally, if a parent attaches a ref to a custom component, React does not pass that ref down as a prop the way it does with other values — the ref is simply dropped, because function components have no instance to attach it to. forwardRef solves this by wrapping the component definition in a function that receives both props and a second ref argument, which the component can then manually attach to whichever underlying DOM node (like an <input>) makes sense, effectively passing the ref through the abstraction. This is essential for building reusable component libraries — for example, a custom TextInput wrapper needs forwardRef so that a parent can still call inputRef.current.focus() on the actual underlying <input> element, exactly as if there were no wrapper at all. It’s commonly paired with useImperativeHandle when the component wants to expose a curated, custom API on the ref instead of the raw DOM node itself, rather than exposing every native DOM method.
- Lets parents access an underlying DOM node through a wrapping component
- Essential for building reusable, composable component libraries
- Pairs with useImperativeHandle to expose a controlled imperative API
- Preserves DOM-level behaviors like .focus() or .scrollIntoView() through abstraction layers
AI Mentor Explanation
forwardRef is like a team manager who is handed a direct radio channel by the head coach meant for the actual bowler on the field, and the manager’s job is simply to pass that channel through untouched rather than intercepting it for themselves. Without that explicit hand-off, the radio call would just stop at the manager and never reach the bowler who actually needs to act on it. By deliberately forwarding the channel, the coach can still give live instructions directly to the bowler even though the manager sits in between. That deliberate pass-through of a direct control channel, rather than letting it get absorbed, is exactly what forwardRef does with a ref.
Step-by-Step Explanation
Step 1
Wrap the component in forwardRef
Define the component as forwardRef((props, ref) => { ... }) instead of a plain function receiving only props.
Step 2
Attach the ref to the target DOM node
Inside the component, set ref={ref} on the specific inner element the parent should be able to access.
Step 3
Parent creates and passes a ref
The parent calls useRef() and passes it as the ref prop directly to the wrapped component.
Step 4
Optionally curate the exposed API
Pair with useImperativeHandle to expose only specific methods instead of the raw DOM node.
What Interviewer Expects
- Understanding that refs are not passed as regular props and are dropped without forwardRef
- Ability to explain why component libraries need forwardRef for DOM access
- Knowledge of useImperativeHandle for exposing a curated ref API
- A concrete example like forwarding a ref to an <input> for .focus()
Common Mistakes
- Assuming ref works like any other prop on a custom function component by default
- Forgetting to attach the forwarded ref to the actual underlying DOM node
- Using forwardRef when a simple callback prop would be simpler and sufficient
- Exposing the raw DOM node via useImperativeHandle when a curated method set would be safer
Best Answer (HR Friendly)
“forwardRef lets a parent component reach directly into a child component to control an actual DOM element inside it, like focusing an input, even when there’s a custom wrapper component in between. Without it, that direct reference would simply be dropped and the parent couldn’t control the inner element at all.”
Code Example
import { forwardRef, useRef } from 'react'
const TextInput = forwardRef<HTMLInputElement, { label: string }>(
function TextInput({ label }, ref) {
return (
<label>
{label}
<input ref={ref} type="text" />
</label>
)
}
)
function Form() {
const inputRef = useRef<HTMLInputElement>(null)
function handleFocusClick() {
inputRef.current?.focus() // reaches the real <input> through the wrapper
}
return (
<>
<TextInput label="Name" ref={inputRef} />
<button onClick={handleFocusClick}>Focus input</button>
</>
)
}Follow-up Questions
- What happens to a ref prop on a function component that doesn’t use forwardRef?
- How does useImperativeHandle change what a forwarded ref exposes?
- Why doesn’t this pattern apply to class components in the same way?
- How would you type a forwardRef component correctly in TypeScript?
MCQ Practice
1. What happens if a parent passes a ref to a plain function component without forwardRef?
Function components ignore ref by default; forwardRef is required to receive and forward it.
2. What is forwardRef commonly paired with to expose a curated ref API?
useImperativeHandle lets a component control exactly what the forwarded ref exposes to the parent.
3. Why do component libraries typically need forwardRef?
forwardRef preserves direct DOM access (like .focus()) through abstraction layers in reusable components.
Flash Cards
What does forwardRef solve? — It lets a component receive and forward a ref, which is otherwise dropped by function components.
What is forwardRef often paired with? — useImperativeHandle, to expose a curated imperative API instead of the raw DOM node.
Where does the forwarded ref usually get attached? — To the specific underlying DOM node the parent needs to control.
Why do component libraries need this? — So wrapped elements still behave like native ones for ref-based access (e.g. .focus()).