I am working with a component which is wrapped with a ContainerLoading
component which will conditionally render children
with a forwardRef
attached to one of the child components (TestChild
) once loading is complete. When wrapped with this component, the passed ref will initially render on page load as undefined
(as it hasn't been rendered yet) and will continue to remain undefined
until the child is rendered.
ContainerLoading.jsx
const ContainerLoading = ({ children, loading, loadingMessage }) => {
return (
<>
{loading && <>{loadingMessage && <p>{loadingMessage}</p>}</>}
{!loading && children}
</>
);
};
App.jsx
export default function App() {
const testRef = useRef();
const [loading, setLoading] = useState(true);
useEffect(() => {
console.log("Your div object", testRef.current);
}, []);
useEffect(() => {
setTimeout(() => {
setLoading(false);
}, 1000);
});
return (
<ContainerLoading loading={loading} loadingMessage={"Loading"}>
<h1 style={{ textAlign: "center" }}>Nested Ref Demo</h1>
<div
style={{
display: "flex",
justifyContent: "center",
alignItems: "center",
flexWrap: "wrap"
}}
>
<TestChild ref={testRef} />
</div>
</ContainerLoading>
);
}
I've discovered that I can utilize a useEffect
with testRef.current
as a dependency to determine when the ref is initialized, though I've read that this is an anti-pattern (https://mcmap.net/q/141855/-is-it-safe-to-use-ref-current-as-useeffect-39-s-dependency-when-ref-points-to-a-dom-element) and we should be utilizing a useCallback
pattern to set the ref, as shown below:
const handleSetRef = useCallback((node) => {
setRef(node);
}, []);
// Code removed for brevity
<TestChild ref={handleSetRef} />
Unfortunately this pattern doesn't seem to work due to the ContainerLoading
component in combination with the TestChild
component also utilizing a forwardRef
. The only way I can think to get this working properly is to utilize the aforementioned anti-pattern.
Note that when changing TestChild
to a div
, everything works properly.
Any thoughts on how to accomplish what I need, preferably without modifying the either the TestChild
or ContainerLoading
components? Thanks!
TestChild
to adiv
, thehandleRef
callback gets called automatically on page load. If I leave it asTestChild
, thathandleRef
doesn't get called until there's a re-render. I'm trying to figure out why when the element is a child component it doesn't work, but when it's simply adiv
it does. Hopefully that makes sense! – Tetter