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.

Ref Hooks

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.

Try It — React Hooks Reference

Open full tool