'Confused about how to create a ref if there is no forward ref?
There are three options, I don't know which one is the best.
//@ts-nocheck
import React, { useEffect, useRef } from "react";
export const Child = React.forwardRef((props, ref) => {
console.log("ref: ", ref);
// option 1
// const divRef = ref || React.createRef();
// option 2, it's same with option 3?
// const _ref = useRef(null);
// const divRef = ref || _ref;
// option 3, one line
const divRef = useRef(ref?.current);
useEffect(() => {
console.log("divRef: ", divRef.current);
}, []);
return <div ref={divRef}>child</div>;
});
Use Child
component inside Parent
component:
const Parent = () => (
<div>
<Child />
</div>
);
render(<Parent />);
As you can see, the Parent
component didn't create and pass ref to Child
. The logic is if the Parent
passed ref, use it, if not, create one in the Child
component
When I run it and check the console log, all of them seem correct because I can get the divRef
.
divRef: <ref *1> HTMLDivElement {...}
Solution 1:[1]
You can easily dismiss the 1st and 3rd options:
- 1st (
createRef
) would create a new ref on each render. - 3rd option
useRef(ref?.current)
doesn't support callback refs, and won't update when the ref changes, since it's passed as initial value.
So the 2nd option would allow external or internal refs, and would also support external function refs:
export const Child = React.forwardRef((props, ref) => {
const _ref = useRef(null);
const divRef = ref ?? _ref;
useEffect(() => {
console.log("divRef: ", divRef.current);
}, []);
return <div ref={divRef}>child</div>;
});
Solution 2:[2]
Although they are not too different and not so significant in terms of performance, I would go for Option 1
for these reasons:
- With option 2:
useRef
will be invoked matter if the parent's ref has existed or not. - With option 3: It's not necessary to create another ref if it's already existed by reference to
ref?.current
again - Finally option 1: The right side of
||
basically won't' invoke if the left side is true.
Anyway, you should not use createRef
inside the functional component for a few reasons.
Or I might miss something, happy to receive any opinions.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | Ryan Le |