What is forwardRef?
In React, `forwardRef` is a function that allows you to pass a ref from a parent component down to one of its children. This is particularly useful when you need a parent component to imperatively access the underlying DOM element or a child component instance of a functional component.
What is `forwardRef`?
React.forwardRef is a higher-order component that enables components to expose a DOM ref to their parent component. By default, functional components cannot receive a ref directly from a parent component because ref is a special prop that React handles internally for class components and DOM elements.
When you try to pass a ref attribute to a functional component directly, React will warn you that refs cannot be attached to functional components. forwardRef solves this by providing a mechanism to 'forward' that ref through the functional component to an underlying DOM element or another React component within it.
Why use `forwardRef`?
- Imperative DOM Interactions: The most common use case is when you need to programmatically interact with a DOM element exposed by a child component, such as focusing an input field, triggering animations, or measuring its size.
- Reusable Component Libraries: When building reusable UI components, you might want to give users of your component the ability to access the underlying DOM node for advanced scenarios.
- Integrating with Third-Party Libraries: Some libraries might require direct DOM access to elements rendered by your React components.
How to use `forwardRef`
To use forwardRef, you wrap your functional component with it. Your component's render function will then receive props as its first argument and ref as its second argument.
1. Define the child component with `forwardRef`
import React, { forwardRef } from 'react';
const MyInput = forwardRef((props, ref) => {
return (
<input type="text" ref={ref} {...props} />
);
});
export default MyInput;
In this example, MyInput is a functional component wrapped with forwardRef. It receives ref as its second argument, which is then attached to the native <input> DOM element. Any ref passed from the parent will now point to this actual input DOM node.
2. Use the component in a parent
import React, { useRef, useEffect } from 'react';
import MyInput from './MyInput';
function ParentComponent() {
const inputRef = useRef(null);
useEffect(() => {
if (inputRef.current) {
inputRef.current.focus(); // Imperatively focus the input
}
}, []);
return (
<div>
<p>Click the button to focus the input via ref:</p>
<MyInput ref={inputRef} placeholder="Type here..." />
<button onClick={() => inputRef.current.focus()}>Focus Input</button>
</div>
);
}
export default ParentComponent;
The ParentComponent uses useRef to create a ref, then passes it to MyInput. Because MyInput was wrapped with forwardRef, the inputRef.current will correctly point to the underlying <input> DOM element, allowing the parent to call methods like focus() on it.
Key Considerations
refas the Second Argument: Remember that therefis always the second argument to the render function passed toforwardRef, not a regular prop.- Display Name: Components wrapped with
forwardRefwill have a default display name likeForwardRefin React DevTools. It's good practice to set a customdisplayNamefor easier debugging:MyInput.displayName = 'MyInput'; - Avoid Overuse: Only use
forwardRefwhen genuinely necessary for imperative actions. Most data flow in React should happen via props and state.
forwardRef is a powerful tool for bridging the gap between parent components needing imperative access and functional child components, ensuring that refs behave consistently across your React application.