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>
}
React documentation says:
You may not use the ref attribute on function components because they don’t have instances. (more)
This means that you can't bind your refs to functional components. That's why your ref2.current
is null
. If you want to bind ref to component, you need to use class components. Your ref1
is not a ref to the Comp1
component. It actually contains an object that you passed in useImperativeHandle
hook. i.e. it contains the next object:
{
print: () => {
console.log('comp1')
}
}
You have to use forwardRef
with functional components if you want to bind your ref with some HTML element or class component that your component renders. Or you could bind your ref with some object with using of useImperativeHandle
hook.
UPDATE
The using of useImperativeHandle
is the same as adding methods to your class component:
class Comp1 extends React.Component {
print() {
console.log('comp1');
}
render() {
return (<div>comp1</div>)
}
}
is the same as
const Comp1 = forwardRef((props, ref) => {
useImperativeHandle(ref, () => ({
print: () => {
console.log('comp1')
}
}), []);
return <div>comp1</div>
});
You asked in a comment:
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?
Answer: Using of useImperativeHandle
is the same bad practice as calling child component methods by refs in class components. React doc says that you should avoid calling child component methods by refs, you should avoid using of useImperativeHandle
. Also, you need to avoid using refs where you can do things without them.