forwardRef
forwardRef
By default, functional components in React do not expose a ref attribute. If you try to pass a ref to a custom functional component, it will be ignored, and React will throw a warning in the console.
function MyInput(props) {
return <input {...props} />;
}
function App() {
const ref = useRef(null);
// ❌ Warning: Function components cannot be given refs.
return <MyInput ref={ref} />;
}
To allow a custom component to receive a ref from its parent and forward it down to a specific DOM element inside it, you must wrap the component in forwardRef.
Syntax
import { forwardRef } from 'react';
const MyComponent = forwardRef(function MyComponent(props, ref) {
// ...
});
When you wrap a component in forwardRef, the render function receives a second argument: the ref itself. You can then attach this ref to whatever DOM element you want.
Example: Creating a reusable Input component
If you are building a UI library, you want your custom <FancyInput> to behave exactly like a native <input>, meaning parents should be able to focus it.
import { forwardRef, useRef } from 'react';
// 1. Wrap the component in forwardRef
// 2. Accept the 'ref' as the second parameter
const FancyInput = forwardRef(function FancyInput(props, ref) {
return (
<div className="fancy-input-wrapper">
<label>{props.label}</label>
{/* 3. Attach the forwarded ref to the actual DOM node */}
<input
ref={ref}
className="fancy-input"
value={props.value}
onChange={props.onChange}
/>
</div>
);
});
// --- Usage ---
function Form() {
const inputRef = useRef(null);
const handleClick = () => {
// The parent can now directly focus the <input> nested inside FancyInput
inputRef.current.focus();
};
return (
<form>
<FancyInput ref={inputRef} label="Username" />
<button type="button" onClick={handleClick}>
Focus Input
</button>
</form>
);
}
When should you use forwardRef?
You generally only need forwardRef when building highly reusable “leaf” components (like Buttons, Inputs, Dialogs, or Tooltips) where the consuming parent components might reasonably need to manage focus, scrolling, or measurements.
You do not need to use forwardRef for higher-level structural components (like a Sidebar or UserProfile). If a parent really needs to interact with something deep inside a structural component, it usually indicates a flaw in the state architecture.
Interview Questions
Q: Why do we explicitly need React.forwardRef?
A: By default, you cannot pass a ref prop to a custom functional component because ref is a reserved keyword in JSX. forwardRef acts as an opt-in mechanism, allowing a functional component to explicitly accept a ref from a parent and “forward” it down to a native DOM element inside of it.