Lesson 6 — forwardRef in React | Real-World Use Cases

🧭 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 forwardRef really 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 forwardRef works 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:

ref is 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:

  • ref is 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)

FeaturePropsRef
PurposeData flowImperative access
Triggers renderYesNo
Passed automaticallyYesNo
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)

Leave a Comment