Mastering React Forwarding Refs: Access Child DOM Nodes the Right Way
Last updated 4 months, 2 weeks ago | 333 views 75 5
Introduction: Why React Forwarding Refs Matters
In React, refs are powerful tools that let you directly access a DOM node or a React component instance. They’re commonly used for:
-
Focusing an input
-
Triggering animations
-
Reading dimensions
-
Managing scroll positions
However, when you're using custom components, simply passing a ref won’t work as expected. That’s because refs do not automatically propagate through components — unless you explicitly forward them using React Forwarding Refs.
This article will help you understand what forwardRef() is, how it works, and when to use it — all explained with clear examples and best practices.
What is React Forwarding Refs?
React Forwarding Refs is a technique that lets you pass a ref through a component to one of its child DOM elements.
By default, if you attach a ref to a functional component, it won't point to the DOM node. forwardRef() bridges that gap.
Why It's Useful
-
Enables ref access to custom components like
<MyInput /> -
Essential for higher-order components (HOCs) and UI libraries
-
Needed for imperative UI interactions
How to Use React Forwarding Refs
1. The Problem Without Forwarding Refs
function MyInput() {
return <input type="text" />;
}
function App() {
const inputRef = useRef();
return <MyInput ref={inputRef} />; // ❌ Won’t work
}
You’ll get a warning: Function components cannot be given refs.
2. Solution: Use forwardRef()
import React, { forwardRef, useRef } from 'react';
// Step 1: Wrap the component with forwardRef
const MyInput = forwardRef((props, ref) => {
return <input ref={ref} {...props} />;
});
// Step 2: Use the ref in the parent
function App() {
const inputRef = useRef();
const focusInput = () => {
inputRef.current.focus(); // ✅ Works!
};
return (
<div>
<MyInput ref={inputRef} placeholder="Type here..." />
<button onClick={focusInput}>Focus Input</button>
</div>
);
}
✅ Now, inputRef.current points directly to the input DOM node inside MyInput.
React Forwarding Refs with Custom Logic
You can also combine forwardRef with hooks like useImperativeHandle to expose only selected methods.
import React, { useRef, forwardRef, useImperativeHandle } from 'react';
const FancyInput = forwardRef((props, ref) => {
const inputRef = useRef();
useImperativeHandle(ref, () => ({
focus: () => {
inputRef.current.focus();
},
clear: () => {
inputRef.current.value = '';
}
}));
return <input ref={inputRef} {...props} />;
});
function App() {
const fancyRef = useRef();
return (
<div>
<FancyInput ref={fancyRef} />
<button onClick={() => fancyRef.current.focus()}>Focus</button>
<button onClick={() => fancyRef.current.clear()}>Clear</button>
</div>
);
}
Complete Functional Example: Ref-Forwarding Input Component
// MyInput.js
import React, { forwardRef } from 'react';
const MyInput = forwardRef((props, ref) => {
return (
<input
ref={ref}
type="text"
placeholder="Enter your name"
style={{ padding: '8px', width: '250px' }}
{...props}
/>
);
});
export default MyInput;
// App.js
import React, { useRef } from 'react';
import MyInput from './MyInput';
function App() {
const inputRef = useRef();
const handleFocus = () => {
inputRef.current.focus(); // Imperative DOM access
};
return (
<div style={{ padding: '2rem' }}>
<MyInput ref={inputRef} />
<br /><br />
<button onClick={handleFocus}>Focus the input</button>
</div>
);
}
export default App;
Tips & Common Pitfalls
✅ Best Practices
-
Use
forwardRefonly when a parent needs DOM access to a child component. -
Use
useImperativeHandleto expose specific functions (e.g.,.focus(),.reset()). -
Combine with PropTypes or TypeScript for better ref validation.
❌ Common Mistakes
-
Forgetting to wrap the component in
forwardRef()and expecting ref to work. -
Passing ref as a prop (
<Comp ref={ref} />) in HOCs without forwarding it. -
Trying to use ref directly on functional components without forwarding.
Comparison Table: React Ref Techniques
| Feature | Default Ref | Forwarding Ref | useImperativeHandle |
|---|---|---|---|
| DOM Access | ✅ | ✅ | ✅ |
| Custom Component Support | ❌ | ✅ | ✅ |
| Custom API Exposure | ❌ | ❌ | ✅ |
| Hooks Compatible | ✅ | ✅ | ✅ |
Conclusion: When to Use React Forwarding Refs
React forwardRef is essential when building custom reusable components that need to expose their internal DOM elements to parent components. It’s commonly used in:
-
Form libraries
-
UI toolkits
-
Reusable component libraries
-
Imperative APIs (e.g., animations, focus control)
Key Takeaways
-
Use
forwardRefto expose refs to child DOM nodes. -
Use
useImperativeHandlefor controlled, limited API access. -
Avoid using
refunless truly necessary—React encourages declarative design.