By default, passing a ref to a child input component exposes the entire underlying DOM node, allowing parent components to inspect or mutate anything on it. useImperativeHandle lets a child component customize the exact methods exposed through ref—such as .focus(), .scrollIntoView(), or .reset()—while keeping internal DOM nodes private.
ref PropIn React 19, function components receive ref as a regular prop without wrapping in forwardRef. Inside the child, call useImperativeHandle(ref, createHandle, deps) to return a clean object of permitted methods.
import { useImperativeHandle, useRef } from 'react';
export function FancyInput({ ref, label }) {
const inputRef = useRef(null);
useImperativeHandle(ref, () => ({
focusInput() {
inputRef.current?.focus();
},
clearInput() {
if (inputRef.current) inputRef.current.value = '';
},
}), []);
return (
<label>
{label}
<input ref={inputRef} type="text" />
</label>
);
}
export function SearchForm() {
const fancyRef = useRef(null);
return (
<div>
<FancyInput ref={fancyRef} label="Filter" />
<button type="button" onClick={() => fancyRef.current?.focusInput()}>
Focus Field
</button>
</div>
);
}
Reserve useImperativeHandle for genuine imperative actions that cannot be expressed cleanly via props—such as triggering <video> playback, resetting scroll position in a virtual list, or focusing an internal input inside a composite widget.
useImperativeHandle Mistakes.openModal() or .setDisabled() via useImperativeHandle when passing <Modal isOpen={open} /> as a prop is simpler and fits React's data flow.forwardRef in React 18: If your project still runs React 18 rather than React 19, wrap FancyInput with forwardRef((props, ref) => ...) so ref reaches the component.ref prop?React safely ignores useImperativeHandle when ref is null or undefined without throwing errors.
useImperativeHandle take a dependency array?Just like useMemo, the dependency array ensures the handle object only updates when values captured inside its methods change.
useImperativeHandle combine multiple internal refs?Yes. A single composite form field can wrap two <input> refs internally and expose .focusFirst() and .focusSecond() on one parent ref.
Sign in to track your learning journey, earn industry-recognized certificates, and join our elite developer community.
Quick Access With