forwardRef 允许组件将 ref 转发给子组件的 DOM 节点。

示例 1: 基本用法

const CustomInput = forwardRef<HTMLInputElement, Props>(
  function CustomInput({ label }, ref) {
    return <input ref={ref} />;
  }
);

// 父组件可以访问 input DOM
const inputRef = useRef<HTMLInputElement>(null);
<CustomInput ref={inputRef} label="用户名" />

示例 2: useImperativeHandle 自定义方法

useImperativeHandle(ref, () => ({
  focus() { inputRef.current?.focus(); },
  clear() { inputRef.current.value = ''; },
  getValue() { return inputRef.current?.value ?? ''; },
  setValue(value) { inputRef.current.value = value; },
  shake() { /* 触发动画 */ },
}));

示例 3: 封装多个内部 ref

说明: 组件内部可以有多个 ref,通过 useImperativeHandle 统一暴露需要的方法,隐藏内部实现细节。

示例 4: 组件库风格的 Button

const Button = forwardRef<HTMLButtonElement, ButtonProps>(
  function Button({ variant, size, children, ...props }, ref) {
    return (
      <button ref={ref} className={...} {...props}>
        {children}
      </button>
    );
  }
);

示例 5: React 19 新语法

// React 19+ 不再需要 forwardRef
function NewStyleInput({ ref, placeholder }) {
  return <input ref={ref} placeholder={placeholder} />;
}

// 使用方式相同
<NewStyleInput ref={inputRef} />
注意: React 19 中 ref 可以作为普通 prop 传递, 但 forwardRef 仍然被支持以保持向后兼容性。