forwardRef与ComponentPropsWithRef的区别及自定义组件Ref绑定问题
forwardRef 与 ComponentPropsWithRef 的区别及你的问题解决
核心作用差异
- forwardRef:React 原生 API,专门用来打破函数组件的「ref 隔离」——普通函数组件默认不会接收父组件传递的
ref参数,必须用forwardRef包裹组件,才能把父组件的ref传递到组件内部的 DOM 节点或子组件实例上。 - ComponentPropsWithRef:TypeScript 提供的工具类型,仅用于类型约束——它能提取某个元素(比如
div)或组件的完整 props 类型,并且自动包含该元素对应的 ref 类型(比如HTMLDivElement),本身不具备传递 ref 的能力。
你的代码问题分析
你写的代码有两个关键问题:
- 普通函数组件不会自动接收
ref参数,直接写(ref)是无效的,必须用forwardRef包裹才能正确接收父组件传递的 ref。 - 没有结合类型约束逻辑,导致用
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
相关产品推荐
相关产品推荐

