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。
相关链接
- forwardRef:forwardRef
- useRef:useRef