🧭 Introduction
By now, you know that useRef allows us to access DOM elements and persist mutable values.
But what happens when:
- The DOM element is inside a child component?
- You are building reusable UI components?
- A parent needs to control or focus a child’s input?
❌ By default, refs do not pass through components.
This is exactly the problem that forwardRef solves.
In this lesson, you’ll understand:
- Why refs don’t work with custom components
- What
forwardRefreally does - When and when not to use it
- Real-world patterns used in UI libraries
🎯 What You’ll Learn in This Lesson
By the end of this lesson, you will understand:
- Why refs don’t work on normal components
- How
forwardRefworks internally - How to expose child DOM elements safely
- Real-world examples (inputs, modals)
- Common mistakes and best practices
❓ The Core Problem: Refs Don’t Pass Automatically
❌ This Does NOT Work
function Input() {
return <input />;
}
function App() {
const inputRef = useRef();
return <Input ref={inputRef} />;
}
⚠️ Result:
refis undefined
Why?
👉 React treats ref as a special prop
👉 It is not passed like normal props
🧠 Why React Blocks Refs by Default
Refs are:
- Imperative
- Potentially unsafe
- Meant to be controlled
So React requires explicit permission from a component to expose its internal DOM.
That permission is given using 👉 forwardRef.
🧩 What is forwardRef? (Clear Definition)
forwardRef is:
A React API that allows a component to receive a ref from its parent and forward it to a child element.
In simple terms:
“Yes React, this component allows ref access.”
🧠 forwardRef Syntax
const Component = forwardRef((props, ref) => {
return <element ref={ref} />;
});
Key points:
refis the second argument- Component must be wrapped with
forwardRef
✅ Basic forwardRef Example
Child Component
import { forwardRef } from "react";
const Input = forwardRef((props, ref) => {
return <input ref={ref} />;
});
Parent Component
function App() {
const inputRef = useRef(null);
return (
<>
<Input ref={inputRef} />
<button onClick={() => inputRef.current.focus()}>
Focus Input
</button>
</>
);
}
✅ Works perfectly
✅ Parent controls child DOM safely
🧠 Mental Model (Very Important)
Without forwardRef:
Parent → Child → DOM ❌
With forwardRef:
Parent → Child → DOM ✅
The child explicitly forwards the ref.
🔍 Real-World Use Case 1 — Reusable Input Component
Reusable components often wrap inputs with styling.
❌ Without forwardRef (Broken)
function TextInput(props) {
return <input className="input" />;
}
Parent cannot focus it.
✅ With forwardRef (Correct)
const TextInput = forwardRef((props, ref) => {
return <input ref={ref} className="input" />;
});
Now:
- Forms
- Modals
- Validation libraries
can safely control focus.
🔍 Real-World Use Case 2 — Modal Focus Management
When a modal opens, focus should move inside it.
const ModalInput = forwardRef((props, ref) => {
return <input ref={ref} />;
});
function Modal({ open }) {
const ref = useRef();
useEffect(() => {
if (open) ref.current.focus();
}, [open]);
return open ? <ModalInput ref={ref} /> : null;
}
👉 This pattern is widely used in accessibility-friendly apps.
⚠ forwardRef vs Props (Important Difference)
| Feature | Props | Ref |
|---|---|---|
| Purpose | Data flow | Imperative access |
| Triggers render | Yes | No |
| Passed automatically | Yes | No |
| Needs forwardRef | ❌ | ✅ |
🚨 Common Mistakes with forwardRef
❌ Mistake 1: Using forwardRef Everywhere
Only use it when:
- Parent truly needs DOM access
❌ Mistake 2: Mixing Business Logic with Ref Logic
Keep ref forwarding minimal and intentional.
❌ Mistake 3: Mutating DOM Too Much
Excessive DOM manipulation breaks React’s declarative model.
🧠 forwardRef in UI Libraries (Industry Insight)
Popular libraries use it heavily:
- MUI
- Ant Design
- Chakra UI
- React Hook Form
Why?
- Accessibility
- Composability
- Controlled imperative access
🔗 forwardRef + useImperativeHandle (Preview)
Sometimes you don’t want to expose the entire DOM, only specific methods.
That’s where:
👉 useImperativeHandle comes in
(next lesson 😉)
🎯 Best Practices
✅ Use forwardRef only when necessary
✅ Forward ref to a single DOM node
✅ Combine with useImperativeHandle when needed
✅ Keep components predictable
❓ FAQs — forwardRef
🔹 Can I forward ref to multiple elements?
No. One ref → one target.
🔹 Is forwardRef bad practice?
No. Misusing it is.
🔹 Do I always need forwardRef for custom inputs?
Only if parent needs DOM control.
🔹 Does forwardRef affect performance?
No, when used properly.
🧠 Quick Recap
✔ Refs don’t pass automatically
✔ forwardRef explicitly allows ref access
✔ Essential for reusable components
✔ Widely used in UI libraries
✔ Powerful but should be used carefully
🎉 Conclusion
forwardRef unlocks professional-grade component design.
Once you master it:
- You can build real UI libraries
- You can control focus and accessibility
- You understand how React balances safety and flexibility
This lesson prepares you perfectly for the next step — controlled imperative APIs ⚛️🧠
👉 Next Lesson
Lesson 7 — useImperativeHandle Hook (Controlled Imperative APIs)