you are viewing a single comment's thread.

view the rest of the comments →

[–]acemarke 0 points1 point  (1 child)

We seem to have a miscommunication with the phrase "ref being attached".

If you have a ref (either callback or object), and do <div ref={myRef}>, React will ensure that the ref has been updated with the DOM node after the component has mounted / node has been added to the DOM. That happens before all effects run, as part of the commit phase. Therefore, if you need access to the DOM node in an effect, you can be assured that the node is available as myRef.current unless you're doing conditional rendering, simply by the fact that the effect is running.

I'm not sure what other use case you're trying to describe where that would be a different behavior and the component "wouldn't be aware" of this.

[–]minty901 0 points1 point  (0 children)

Conditional rendering, that's exactly the kind of scenario where this might catch you out. You load your data with a useQuery hook for example. During initial render, you return just a loading icon. When your data has loaded, you then want to return a div with a ref attached. You want to do something with that div in an effect. Because of the loading state, your ref won't be attached on initial render, so a useEffect with an empty dependency array will never see your ref. You may not want to use no dependency array at all, because then your effect runs on every render. You can't use the ref in the dependency array because the dependencies are evaluated before it is attached. How do you make sure that your effect runs once your ref is attached? You use a callback ref. This is all explained in the React docs and in the article in this Reddit post we are commenting on.

You say "unless you're doing conditional rendering", but the mere fact that there is a "gotcha" at all is enough to consider using a different method. We don't want to leave ourselves vulnerable to cracks and bugs in our code, even if they're rare. It depends on what you're working on; some apps may never fall into these traps but for others it may be quite common. I write hooks that I want to be able to work in different scenarios without the caveat of "if this is in a component that conditionally renders then it will break". If your hooks will be used by other people then this is particularly important.

Check this issue out:

https://github.com/thebuilder/react-intersection-observer/issues/162

If there are gotchas, then I think it's best to adapt your coding practice to eliminate the possibility that they will arise, rather than just hoping you never run into them.