solid icon indicating copy to clipboard operation
solid copied to clipboard

Cannot reuse a dom element when switching mount locations

Open thetarnav opened this issue 1 year ago • 7 comments

I'm trying to reuse the same dom element, and attach it in different places in the ui. But even though that element is rendered only in one place at a time, solid's rendering of it is not stable. Sometimes the element is added correctly, sometimes it's removed from the dom completely and sometimes it appears in the wrong spot.

const my_dom_element = document.createElement('div')

return <>
	<div>
		<Show when={something() === 'foo'}>
			{my_dom_element}
		</Show>
	</div>
	<div>
		<Show when={something() === 'bar'}>
			{my_dom_element}
		</Show>
	</div>	
</>

Playground link: https://playground.solidjs.com/anonymous/d2ce885b-d473-4641-94a6-d9c659bc1e22

I know that this can be "solved" by creating new elements and animating them as if they were the old one. But that is besides the point. This just seems like something that should work.

thetarnav avatar Nov 09 '24 08:11 thetarnav

Smaller repro https://playground.solidjs.com/anonymous/e8cab030-93c5-44b5-8f26-f283547cc77e

We have talked about this with Fabio in the past, the conclusion IIRC was that before removing the element we should check if the parent is still the same.

titoBouzout avatar Nov 09 '24 08:11 titoBouzout

It still breaks on this scenario, so I suppose that also won't help https://playground.solidjs.com/anonymous/7c9fcf09-82a0-4131-a1ba-51a37d50dca0

titoBouzout avatar Nov 09 '24 08:11 titoBouzout

I think it would be fine even if you had to explicitly tell the renderer that you want to reuse some element.

const el = createReusable(() => <div/>)

This is a rare case after all

thetarnav avatar Nov 09 '24 08:11 thetarnav

It seems this is a duplicate of https://github.com/solidjs/solid/issues/2030 with almost the same repro as https://github.com/solidjs/solid/issues/2357#issuecomment-2466118652

Edit: nah, only the last comment https://github.com/solidjs/solid/issues/2030#issuecomment-1992705626

mdynnl avatar Nov 11 '24 15:11 mdynnl

There's also https://github.com/ryansolid/dom-expressions/issues/337

And cross posting Voby https://github.com/vobyjs/voby/issues/39 for this very same issue

titoBouzout avatar Nov 11 '24 16:11 titoBouzout

https://discord.com/channels/722131463138705510/1217034387938607145

Yes, but as soon as you put the components in a seperate div, it breaks.

This is exactly what's happening here. And the workaround (for now) is to simply group the nodes https://playground.solidjs.com/anonymous/dfea14d8-e6db-4b76-a3f2-12b3ce0335db

And here's a repro with (almost?) all the ways this can break.

We can solve this by tracking whether a node was moved then ignoring the removal of tracked nodes. (PR coming up)

And then in the case of multiple insertions, intuitively (and how it works currently), the last insertion wins and as a consequence, the internal rendering state is inconsistent with the actual DOM state. Although it's not breaking anything, there's the question whether we should keep this behavior or somehow keep the internal state consistent or keep only the first insertion.

mdynnl avatar Nov 11 '24 16:11 mdynnl

This is tricky to do and outside of expectation currently. But it would be interesting to find a solve in the future.

ryansolid avatar Apr 30 '25 20:04 ryansolid