#Alternatives to ordered For without reparenting

39 messages · Page 1 of 1 (latest)

ionic echo
#

I have an array of ordered elements that I currently render with <For>. However, I'm having some trouble with iframes (such as for youtube embeds) reloading when the array changes. It could be due to the array reconciliation calling replaceChild. Currently unable to prove that. I know iframes cannot be reparented, even to the same parent, without reloading.

So now I'm looking for any For-like component that can avoid that, before writing all the logic myself.

forest egret
#

so all items are unique and it disconnect the player?

ionic echo
forest egret
#

so technically you can't move the iframe element around right?

#

in your scenario, that element does not move , but still disconnect?

ionic echo
#

It may have a sibling removed above and added below (it's part of a chat), but ideally it should never explicitly touch the child with the iframe in it.

Currently trying to replicate in the playground.

#

... Nevermind, I figured out what was going on. Classic SolidJS "Don't pass a closure as a child if you don't want it to rerender for random reasons"

forest egret
#

lol

ionic echo
#

Thanks for reading and being ready to help, anyway. Going to close the post.

forest egret
#

np
this is actually interesting about the iframe, can't move / or lose state.
it is funny, because you can technically, move nodes around it

good interview question haha

if that was an actual problem, then it should be solvable with a single active
player. if you have 2 and they both need to stay connected
then they can't change order between themselves

now we can close, we both have closure

ionic echo
#

Actually, seems I spoke literal seconds too soon. I can no longer replicate the fix. However, it seems preprending elements to that array keeps the iframe playing, but appending or removing elements from the end breaks it.

Even removals in the middle of the array before the current playing iframe works.

forest egret
#

yeah, solid reconciliation is non deterministic ( the new buzz word)

#

it moves stuff until it fits the final state

wispy hazel
#

how are you updating the arrray?

ionic echo
#

The array that goes into <For> is a slice of an array in a SolidJS Store object. The store-d array is updated via produce and splice to add/remove one at a time.

So the array itself is not referentially equal, but the elements are. However, none of the children are recreated, tested that, it's just that iframes are super pissy with how they get moved around.

wispy hazel
#

cant you edit dom-expressions to replace the child diferently?

forest egret
#

yeah it is possible to custom logic it , that will be a lot of work

ionic echo
#

I don't know if I can grok that algorithm well enough, and really it's just this single place that iframes exist, in the main chat. I use For and arrays in general elsewhere of course.

forest egret
#

you are saying that if you append or prepend things still move?

ionic echo
#

Push/pop breaks it, shift/unshift somehow works, is what I'm seeing now.

#

Or splice before the iframe.

wispy hazel
#

if you are sure replaceChild breaks it maybe try something like

          } else parentNode.replaceChild(b[bStart++], a[aStart++]);

to

          } else {
let newChild = b[bStart++]
let oldChild =  a[aStart++]
parentNode.insertBefore(newChild , oldChild );
parentNode.removeChild(oldChild)
]
forest egret
ionic echo
#

setStore(produce(...)), yes.

I may have just figured it out, and it was once again closures.

<ul>
    <For each={feed()}>
        {msg => <Message msg={msg}/>
    </For>
</ul>

where Message had:

<>
    {() => complex_boolean() && <hr/>}

    <li/>
</>

Switching out the closure with other things actually appears to have fixed it (knock on wood again).

#

I had originally chosen to use closures like that because it's much cheaper than Show/Match with their hidden createMemos inside, but <For> apparently really hates them.

forest egret
#

yeah, better to avoid them in solid

ionic echo
#

They work in most places, just not anywhere you expect referential equality of child nodes, I guess.

forest egret
#

they are being deprecated

ionic echo
#

Is there a github issue for that?

ionic echo
#

onError in anything? Wut.

#

I don't know what you mean by the onError comment. That's a standard event for images and such.

#

Oh, okay, unrelated to what I was thinking of, then. Still, mildly annoying that function elements are being deprecated. Such a waste to createMemo on mostly already-memoized booleans and such.

forest egret
#

also when you do this

`()=>complex_boolean() && <hr/>`

is it not memo too?

ionic echo
#

Nope, bypasses it. {complex_boolean() && <hr/>} memoizes, though.

forest egret
#

oh, only on return then I guess

#

oh no only without the wrapper

ionic echo
#

Suppose I could just write my own version of <Show>