跳转到主要内容

useImperativeHandle

让组件在 ref 上暴露一个受控的 API,而不是把内部 DOM 细节直接暴露出去。

Stable

类型签名

TypeScript
function useImperativeHandle<T, R extends T>(
  ref: Ref<T> | undefined,
  init: () => R,
  deps?: DependencyList
): void

参数与返回

  • ref:父组件传入的 ref。
  • init:返回你希望暴露的 handle 对象。
  • deps:可选依赖数组;当依赖变化时重新生成 handle。
  • 返回值:void。

版本与稳定性

  • 稳定性:稳定。
  • 使用建议:仅在需要与 DOM/外部系统交互时使用,尽量保持声明式。

关键用法

TypeScript
import { forwardRef, useImperativeHandle, useRef } from 'react';

type InputHandle = { focus: () => void };

const MyInput = forwardRef<InputHandle, { placeholder?: string }>(
  function MyInput(props, ref) {
    const innerRef = useRef<HTMLInputElement | null>(null);

    useImperativeHandle(ref, () => ({
      focus() {
        innerRef.current?.focus();
      },
    }));

    return <input ref={innerRef} placeholder={props.placeholder} />;
  }
);

export default function App() {
  const ref = useRef<InputHandle | null>(null);
  return (
    <>
      <MyInput ref={ref} placeholder="搜索..." />
      <button onClick={() => ref.current?.focus()}>聚焦</button>
    </>
  );
}

建议

TypeScript
// ✅ 优先使用 props/回调进行声明式控制
// 只有在需要与外部系统对接(焦点、滚动、媒体控制)时才考虑 imperative handle

如果你的目标只是“让子组件把数据传回父组件”,更适合用 props 或回调(事件)而不是 ref。

相关链接

useImperativeHandle - React API 参考 - React 文档