我看到 React.forwardRef 似乎是将 ref 传递给子功能组件的认可方式,来自 react 文档:
const FancyButton = React.forwardRef((props, ref) => (
<button ref={ref} className="FancyButton">
{props.children}
</button>
));
// You can now get a ref directly to the DOM button:
const ref = React.createRef();
<FancyButton ref={ref}>Click me!</FancyButton>;
Run Code Online (Sandbox Code Playgroud)
但是,与简单地传递自定义道具相比,这样做有什么优势?:
const FancyButton = ({ innerRef }) => (
<button ref={innerRef} className="FancyButton">
{props.children}
</button>
));
const ref = React.createRef();
<FancyButton innerRef={ref}>Click me!</FancyButton>;
Run Code Online (Sandbox Code Playgroud)
我能想到的唯一优势可能是为 refs 提供了一致的 api,但还有其他优势吗?传递自定义道具是否会影响渲染时的差异并导致额外的渲染,肯定不会因为 ref 在current字段中存储为可变状态?
例如,假设您想传递多个 refs(这可能表明代码异味,但仍然如此),那么我能看到的唯一解决方案是使用 customRef 道具。
我想我的问题是使用forwardRef自定义道具的价值是什么?
为什么不能将 ref 传递给 React 中的功能组件?
与无法向其传递引用的类组件相比,函数组件有何不同?
为什么那不可能呢?
注意:我提出这个问题是因为我总是看到有关如何将 ref 与功能组件一起使用的解释,并且您需要使用fowardRef,但没有人解释 React 如何处理功能组件,从而无法将 ref 传递给它,它总是解释如何去做,但从来没有解释为什么你需要这样做。
根据 React 文档,将 ref 传递给子组件的正确方法如下:
import React from 'react';
const Input = React.forwardRef((props, ref) => {
React.useEffect(() => {
ref.current.focus();
}, []);
return <input type="text" ref={ref} />;
});
export default function App() {
const inputRef = React.createRef();
return (
<div>
<Input ref={inputRef} />
</div>
);
}
Run Code Online (Sandbox Code Playgroud)
但是,如果我尝试将创建的 ref 作为普通 prop 以任何其他名称(然后是“ref”)传递,这也会按预期工作。
import React from 'react';
const Input = (props) => {
React.useEffect(() => {
props.inputRef.current.focus();
}, []);
return <input type="text" ref={props.inputRef} />;
};
export default function App() {
const inputRef …Run Code Online (Sandbox Code Playgroud) 我正在使用两个类组件,其中我有一个从父组件调用的方法。出于这个原因,我必须使用 React.CreateRef() 创建两个引用。但问题是一个组件允许我使用 ref 属性和 onther innerRef 属性。所以我想知道不同之处。
class X extends Component {
constructor(props) {
super(props);
this.xRef = React.createRef();
this.yRef = React.createRef();
}
render (){
return (
<Xcomponent
classes={classes}
user={user}
ref={this.xRef }
/>
<Ycomponent
classes={classes}
user={user}
innerRef={this.xRef }
/>
)
}
}
Run Code Online (Sandbox Code Playgroud) const ref = useRef()
React.Children.map(this.props.children, (element) => {
React.cloneElement(element, {
innerRef: node => ref,
})
})
Run Code Online (Sandbox Code Playgroud)
这里元素是一个组件
像下面这样
const newComponent = forwardRef(({children, ...otherprops}, ref){
return (
<div {...otherprops} ref={otherprops.innerRef}>
{children}
</div>
)
})
Run Code Online (Sandbox Code Playgroud)
得到ref是null在 forwardRef ...
可重现的示例:- https://codesandbox.io/s/forward-ref-cloneelement-1msjp