const Comp1 = forwardRef((props, ref) => {
useImperativeHandle(ref, () => ({
print: () => {
console.log('comp1')
}
}), []);
return <div>comp1</div>
});
const Comp2 = () => <div>comp2</div>;
const App = () => {
const ref1 = useRef(null);
const ref2 = useRef(null);
useEffect(() => {
console.log(ref1); // prints ref1 with the expected current
console.log(ref2); // prints ref2 with current: null
})
return <div><Comp1 ref={ref1}/><Comp2 ref={ref2}/></div>
}
https://codepen.io/benma/pen/mddEWjP?editors=1112
最佳答案
react 文档说:
You may not use the ref attribute on function components because they don’t have instances. (more)
这意味着您不能将 refs 绑定(bind)到功能组件。这就是为什么您的
ref2.current
是 null
.如果要将 ref 绑定(bind)到组件,则需要使用类组件。您的 ref1
不是对 Comp1
的引用成分。它实际上包含您传入的对象 useImperativeHandle
钩。即它包含下一个对象:{
print: () => {
console.log('comp1')
}
}
您必须使用
forwardRef
如果要将 ref 与组件呈现的某些 HTML 元素或类组件绑定(bind),请使用功能组件。或者您可以使用 useImperativeHandle
将您的 ref 与某个对象绑定(bind)钩。更新
useImperativeHandle
的使用与向类组件添加方法相同:class Comp1 extends React.Component {
print() {
console.log('comp1');
}
render() {
return (<div>comp1</div>)
}
}
是相同的
const Comp1 = forwardRef((props, ref) => {
useImperativeHandle(ref, () => ({
print: () => {
console.log('comp1')
}
}), []);
return <div>comp1</div>
});
你在评论中问:
So after moving to hooks (and still avoid using classes), the only way to use ref is to use
useImperativeHandle
(and actually use a "fake" ref)? Is this a good practice?
答案:使用
useImperativeHandle
与通过类组件中的 refs 调用子组件方法相同的坏习惯。 React doc 说你应该避免通过 refs 调用子组件方法,你应该避免使用 useImperativeHandle
.此外,您需要避免在没有它们的情况下可以做事情的地方使用 refs。
关于reactjs - React 钩子(Hook)和功能组件引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58411779/