ref作为属性传递与props传递的区别及forwardRef必要性探讨
React forwardRef 与自定义props传递ref的区别
首先,React.forwardRef 的官方定义是:
React.forwardRef 创建一个React组件,它会将接收到的ref属性转发给树中的另一个组件。
方式一:使用 forwardRef
import { forwardRef, useRef } from "react"; import "./styles.css"; export default function App() { return <Parent />; } function Parent() { const ref = useRef(); const onClick = () => { ref.current.focus(); }; return ( <> <Child ref={ref} /> <button onClick={onClick}>click me</button> </> ); } const Child = forwardRef((props, ref) => { return <input ref={ref} type="text" />; });
方式二:通过自定义props传递ref
import { useRef } from "react"; import "./styles.css"; export default function App() { return <Parent />; } function Parent() { const ref = useRef(); const onClick = () => { ref.current.focus(); }; return ( <> <Child myRef={ref} /> {/* 通过props传递ref */} <button onClick={onClick}>click me</button> </> ); } const Child = ({ myRef }) => { return <input ref={myRef} type="text" />; };
两种方式的核心区别
语义与规范一致性
forwardRef是React官方推荐的标准ref转发方案,其他开发者看到组件上的ref属性时,能立刻明白这是在获取子组件内部的DOM节点或组件实例,符合统一的语义规范。- 自定义props(如
myRef)属于非标准命名,不同开发者可能用inputRef、innerRef等不同名称,代码的可读性和一致性会受影响。
生态工具兼容性
- 多数React生态库(如UI组件库、高阶组件)是基于
forwardRef设计的。比如用React.memo包裹组件时,要传递ref必须配合forwardRef;部分第三方组件仅支持通过标准ref属性获取内部元素。 - 自定义props传递ref无法直接兼容这些依赖标准ref的工具和组件。
- 多数React生态库(如UI组件库、高阶组件)是基于
ref的特殊性处理
- React中
ref是特殊属性,不会被包含在组件的props对象里(forwardRef中ref是单独的第二个参数),避免了ref与普通props混淆。 - 自定义props会被当作普通props处理,可能和组件内部其他props命名冲突,或在传递链中被意外修改。
- React中
高阶组件(HOC)场景必要性
- 编写高阶组件时,若要把外部传入的ref转发给被包裹的原始组件,必须使用
forwardRef。如果用自定义props,HOC需要额外处理该props的传递,代码会更繁琐且不标准。
- 编写高阶组件时,若要把外部传入的ref转发给被包裹的原始组件,必须使用
forwardRef是否不再必要?
当然不是。自定义props传递ref仅适用于简单的父子组件场景,但在复杂组件结构、生态工具兼容、语义规范等场景下,forwardRef是不可替代的。它是React官方提供的标准解决方案,保障了ref传递的规范性、兼容性和可读性。
内容的提问来源于stack exchange,提问作者JieamI
相关产品推荐
相关产品推荐

