How can I only set the ref for an element once it's been inserted into the DOM?
I've tried a few things but it doesn't seem like the element is inserted to the DOM at the point where the
ref
is called, which does make a bit of sense, but I just can't find a proper escape hatch for this.
Tried:
- Using setTimeout(..., 0)
before setting
- Checking if document.contains(...)
before setting
- Using a hacky Mutation observer, not sure if I did my best on this one but doesn't seem optimal
For background, my use case is wit using https://github.com/lxsmnsyc/solid-floating-ui/tree/main (from @lxsmnsyc š¤). The issue seems to happen when floating-ui
itself tries to resolve the parent nodes for the floating
element which do not exist at the point where the element hasn't yet been inserted in the DOM.GitHub
GitHub - lxsmnsyc/solid-floating-ui: SolidJS bindings for Floating UI
SolidJS bindings for Floating UI. Contribute to lxsmnsyc/solid-floating-ui development by creating an account on GitHub.
24 Replies
Someone else also seems to run into this https://github.com/lxsmnsyc/solid-floating-ui/issues/6
How are you setting the ref?
I would suggest using a signal ref if you're not already
yup, doing that
doing it pretty conventionally, so something like:
I do have a mergeRef from
@solid-primitives/refs
though
but I don't think it would make much of a differenceHmm, could be a bug possibly
pretty sure something could be done inside solid-floating-ui that could get around this, like making sure that the element has been inserted
not sure how to get to that reactively with Solid though, I can only think of having a MutationObserver
elements are not mounted when ref is called, they are only mounted after the ref function is called, in the effect phase (unless you created the element without mounting it immediately i.e. outside the return; don't do that), which is when the floating-ui integration tries to get them
the problem is probably that you have it in a Show that's gone from showing to not showing, so the element isn't mounted
the preferred solution is to set the ref to null/undefined when the Show goes to false
if it isn't working on initial render then it's possible something further up is creating the element without actually mounting it other than suspense
hmm yeah don't think that's it, logging the state that goes into the
when
prop on a render effect doesn't only logs once
though the ref callback does get called twice apparently
tried doing that but it seems like it still errors
I'll try getting a reproduction outthere's not much to touch in solid-floating-ui though
Gabriel Miranda
StackBlitz
Reproduction of issue with solid-floating-ui - StackBlitz
A Solid TypeScript project based on @floating-ui/dom, solid-floating-ui, solid-js, solid-transition-group, typescript, vite, vite-plugin-solid and csstype
wasn't able to add a ErrorBoundary to this
so the error only appears only in the console for some reason
you just need to click the button
hmm, so how what do you recommend I do to avoid this kind of thing?
fixes the issue in the repro
oh missed the parenthesis š , then I think it might be something else than what I've thought
on second thought I think this might be the issue here
this sounds like you're calling
props.children
twice somewhere
which would cause this if one of them was being discardedhmm yeah I actually kind of am
here
yes don't do that
What's another way to do this, like on a createMemo with an
on
?if you must, use the
children
helper
though if for some reason what you're doing there somehow works the same way in dev and prod (it doesn't if hmr still adds the extra accessor), you could do
yeah I'll try doing this, using
children
ended up needing too much type finaglingit probably works, but i can't really say it's robust
would be better
well that might complain about too many args
yeah, the refs being called multiple times was that, and now its gone, but the show was actually going back and forth as you mentioned LOL
so it was both then
yeah, I was too stubborn š
thank you so much for your time man, helped me a ton
šš»
btw I did all the things that were mentioned here and it is still not working, so I had to scrap solid-floating-ui from my project š¦
the only solution that worked for me is to migrate my tooltip, and popover components to corvu https://corvu.dev/docs/, which also uses floating-ui, but does not have this issue š