useImperativeHandle lets a component replace the DOM node exposed through a ref with a custom object. The parent then sees only the methods you choose, keeping the child's internals private. It is an escape hatch for imperative behavior that cannot be expressed as props.
What it does and when to use it
The Hook is stable and imported from react. In React 19 and later you receive ref as a prop, so you call useImperativeHandle directly instead of going through forwardRef.
| Argument | Role |
|---|---|
| ref | The ref prop received from the parent. |
| createHandle | A function that returns the object to expose. |
| dependencies | Optional array of reactive values read inside createHandle. |
The Hook returns undefined. It works by reassigning what the parent sees when it reads the ref, rather than producing a value you render.
Expose a limited input API
A parent often only needs focus, not the whole input element. Keep the real DOM node in a private ref and expose a single focus method.
import { useRef, useImperativeHandle } from "react";
function MyInput({ ref }) {
const inputRef = useRef(null);
useImperativeHandle(ref, () => ({
focus() {
inputRef.current.focus();
},
}), []);
return <input ref={inputRef} />;
}The child holds the actual input in inputRef, then exposes only focus through the handle. The parent cannot read the input's style or any other DOM property.
import { useRef } from "react";
function Form() {
const inputRef = useRef(null);
return (
<>
<MyInput ref={inputRef} />
<button onClick={() => inputRef.current.focus()}>Focus</button>
</>
);
}Clicking the button calls the exposed focus method. The empty dependency array tells React to build the handle once, since the methods never change. The parent reads the handle through the same ref object, but only the focus method is reachable.
Expose your own methods
The handle does not have to mirror DOM methods. It can combine several steps under one method name.
import { useRef, useImperativeHandle } from "react";
function SearchBox({ ref }) {
const inputRef = useRef(null);
useImperativeHandle(ref, () => ({
focusAndSelect() {
inputRef.current.focus();
inputRef.current.select();
},
}), []);
return <input ref={inputRef} />;
}The child exposes one method that focuses the field and selects its text. The parent never needs to know that two DOM calls are involved.
import { useRef } from "react";
function Form() {
const inputRef = useRef(null);
return (
<>
<SearchBox ref={inputRef} />
<button onClick={() => inputRef.current.focusAndSelect()}>Select</button>
</>
);
}Clicking the button selects the text inside the input. The implementation stays hidden inside SearchBox.
Prefer props over imperative handles
Imperative handles are a last resort. If a behavior can be expressed as a prop, use a prop instead. A Modal should take an isOpen prop rather than expose open and close methods through a ref.
Imperative code is harder to trace than declarative props, because it runs outside the normal data flow. See how to pass refs between components for the plain forwarding alternative.
What to learn next
A ref can be either an object or a function. Continue with callback refs vs object refs.
Rune AI
Key Insights
- useImperativeHandle(ref, createHandle, dependencies?) customizes the exposed handle.
- Keep the real DOM node in a separate ref inside the child.
- The handle exposes only the methods you return.
- Use it for focus, scroll, and similar imperative actions.
- Prefer props like isOpen over imperative methods when possible.
Frequently Asked Questions
What does useImperativeHandle return?
When should I use useImperativeHandle?
Do I need forwardRef with useImperativeHandle?
Conclusion
useImperativeHandle swaps the DOM node exposed through a ref for a custom object you control. It keeps a child's internals private while letting a parent call a small set of imperative methods.
More in this topic
How to Build a Dropdown Menu in React
Build a React dropdown menu with the ARIA menu button pattern. Handle open and close, keyboard arrows, and clicks outside the menu.
How to Animate React Components with Motion
Animate React components with the Motion library. Set up motion, add enter, hover, and exit animations, and respect reduced motion.
Headless UI Components Explained: Logic Without Locked Styling
Understand headless UI components and how libraries like Radix give you unstyled, accessible behavior that you style yourself.