You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

forwardRef与ComponentPropsWithRef的区别及自定义组件Ref绑定问题

forwardRef 与 ComponentPropsWithRef 的区别及你的问题解决

核心作用差异

  • forwardRef:React 原生 API,专门用来打破函数组件的「ref 隔离」——普通函数组件默认不会接收父组件传递的 ref 参数,必须用 forwardRef 包裹组件,才能把父组件的 ref 传递到组件内部的 DOM 节点或子组件实例上。
  • ComponentPropsWithRef:TypeScript 提供的工具类型,仅用于类型约束——它能提取某个元素(比如 div)或组件的完整 props 类型,并且自动包含该元素对应的 ref 类型(比如 HTMLDivElement),本身不具备传递 ref 的能力。

你的代码问题分析

你写的代码有两个关键问题:

  1. 普通函数组件不会自动接收 ref 参数,直接写 (ref) 是无效的,必须用 forwardRef 包裹才能正确接收父组件传递的 ref。
  2. 没有结合类型约束逻辑,导致用 ComponentPropsWithRef 时类型不匹配,自然无法正常添加 ref。

正确写法(结合 TypeScript)

import { forwardRef, ComponentPropsWithRef, useRef } from 'react';

// 用 ComponentPropsWithRef 提取 div 的完整 props 类型(包含 ref 类型)
type MyComponentProps = ComponentPropsWithRef<'div'>;

// 用 forwardRef 包裹组件,接收 props 和 ref 两个参数
// 泛型第一个参数是 ref 指向的目标类型,第二个是组件的 props 类型
const MyComponent = forwardRef<HTMLDivElement, MyComponentProps>((props, ref) => {
  // 把 ref 绑定到内部 div,同时透传其他 props
  return <div ref={ref} {...props}>Some text</div>;
});

// 使用示例
function App() {
  const divRef = useRef<HTMLDivElement>(null);
  return <MyComponent ref={divRef} className="my-class" />;
}

关键细节总结

  • ComponentPropsWithRef 只是帮你快速生成包含 ref 类型的 props 定义,必须配合 forwardRef 才能让组件真正具备接收并传递 ref 的能力。
  • 如果不用 TypeScript,只需要用 forwardRef 包裹组件即可,不需要 ComponentPropsWithRef。

内容的提问来源于stack exchange,提问作者parlament

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 14:59:53