Capítulo 56 de 116

Chapter 56: useImperativeHandle

Core Idea

useImperativeHandle(ref, createHandle, dependencies?) lets a component customize exactly what a parent's ref receives — instead of exposing the raw underlying DOM node, it exposes a deliberately limited, custom object of methods/values.

Key Concepts

  • Signature: useImperativeHandle(ref, createHandle, [deps]) — called inside the child component that receives ref as a prop; createHandle returns the object the parent's ref.current will actually be set to.
  • Why restrict the exposed surface: giving a parent the full DOM node (via plain ref forwarding) lets it do anything — resize, restyle, remove children the component itself manages. Returning a narrow custom object (e.g. just { focus(), scrollIntoView() }) keeps the parent's capabilities intentional and limits coupling to the component's internal DOM structure.
  • Pairs with a ref prop on the child: the child component declares a ref parameter (modern React) and passes it into useImperativeHandle — the parent then calls <Child ref={childRef} /> and interacts only through the exposed methods, not the raw node.
  • Dependencies work like useMemo/useCallback: the exposed handle object is only recreated when a listed dependency changes, avoiding a fresh object (and thus a changed ref.current identity) on every render.

Code Examples

function MyInput({ ref, ...props }) {
  const inputRef = useRef(null);
  useImperativeHandle(ref, () => ({
    focus() { inputRef.current.focus(); },
  }));
  return <input ref={inputRef} {...props} />;
}
// Parent: myInputRef.current.focus() — only `focus` is exposed, not the raw node
  • What it demonstrates: a parent gets a .focus() method without gaining direct access to inputRef's actual DOM node or any other of its properties.

Key Takeaways

  1. Reach for this when a component needs to expose some imperative capability to a parent, but exposing the raw DOM node would be too permissive.
  2. The createHandle function's dependency array follows the same rules as useMemo/useCallback — list what it actually reads.
  3. This is an uncommon Hook — most component communication should stay declarative (props/state); reserve this for genuine imperative-API needs (focus management, imperative animation triggers, etc.).

Connects To

  • Ch 35 (Manipulating the DOM with Refs): the raw ref-forwarding this Hook deliberately restricts.
  • Ch 34 (Referencing Values with Refs): the underlying ref mechanics.