React useImperativeHandle — Exposing Custom Component APIs
Learn how to use useImperativeHandle to expose a custom API from a child component to its parent via refs. Covers forwardRef, video players, form validation, and modal controls.
Detailed Explanation
Custom Component APIs with useImperativeHandle
useImperativeHandle lets you customize what the parent sees when it uses a ref on your component. Instead of exposing the entire DOM node, you expose only the methods you want.
The Pattern
import { forwardRef, useImperativeHandle, useRef } from "react";
interface ModalHandle {
open: () => void;
close: () => void;
}
const Modal = forwardRef<ModalHandle, { children: React.ReactNode }>(
function Modal({ children }, ref) {
const dialogRef = useRef<HTMLDialogElement>(null);
useImperativeHandle(ref, () => ({
open() { dialogRef.current?.showModal(); },
close() { dialogRef.current?.close(); },
}));
return <dialog ref={dialogRef}>{children}</dialog>;
}
);
Usage in the Parent
function App() {
const modalRef = useRef<ModalHandle>(null);
return (
<div>
<button onClick={() => modalRef.current?.open()}>Open</button>
<Modal ref={modalRef}>
<h2>Hello!</h2>
<button onClick={() => modalRef.current?.close()}>Close</button>
</Modal>
</div>
);
}
Form Validation Example
interface FormHandle {
validate: () => boolean;
reset: () => void;
getValues: () => Record<string, string>;
}
This pattern lets parent components trigger validation imperatively while the form component manages its own internal state.
When to Use
- Building reusable UI library components (modals, drawers, video players)
- Components that wrap third-party imperative APIs
- When the parent needs to trigger specific actions that cannot be modeled as props
When NOT to Use
Most communication should happen through props and state. Imperative handles are an escape hatch for cases where declarative patterns are insufficient.
Use Case
Use useImperativeHandle for reusable library components like modals, video players, form validators, and rich text editors that need to expose specific imperative methods to parent components.