React forwardRef and useImperativeHandle Explained
Ever built a React component where a button in the parent needs to trigger something inside a child ? Like submitting or validating a form inside a SideSheet / Modal ?
You click “Save” on the SideSheet… but your form logic lives deep inside another component. How do you reach it?
That’s where forwardRef (and its partner useImperativeHandle) step in.
What is forwardRef?
Normally, data in React flows from parent to child through props. But sometimes, a parent needs a shortcut to directly access a child’s DOM node or internal method.
forwardRef gives that shortcut — it allows you to pass a ref from parent to child.
In simple terms:
“Hey child, I’ll give you this handle so I can call you later if I need to.”
💡 The Example: SideSheet + Form
Imagine this setup:
When “Save” is clicked, you want to:
Let’s see how we’d do this — first without, then with forwardRef.
🚫 Without forwardRef
We can try to hack it by passing callbacks around.
🧩 Child: UserForm
Here, we’re trying to be clever. The child form calls onSubmit(submitForm) — basically sending its internal submitForm function to the parent. This way, the parent can trigger the form’s logic whenever it wants.
🧩 Parent: SideSheet
Recommended by LinkedIn
😬 Why This Becomes a Problem
✅ With forwardRef + useImperativeHandle
🧩 Child: UserForm
🧩 Parent: SideSheet
What’s Actually Happening
formRef.current.submitForm();
formRef.current.validate();
without breaking React’s one-way flow.The child exposes only what’s needed — not its entire internal state.
Why we need useImperativeHandle
When you forward a ref, it usually points to a DOM node (<input>). But sometimes, you want to expose your own functions instead of DOM methods.
That’s what useImperativeHandle does — it defines a custom interface for the parent to use.
In other words:
The child decides what the parent is allowed to touch.
Conclusion
forwardRef and useImperativeHandle give you a clean, React-idiomatic way to let parent components talk to their children — without breaking React’s one-way data flow.
Instead of juggling callbacks or lifting too much state, these hooks let you safely expose just what the parent needs — like submitForm() or resetForm() — while keeping your component encapsulated and reusable.
They don’t cause re-renders, they keep your logic predictable, and they make your code easier to maintain as your app grows.