SolidJS Stores + SortableJS - Weird update bug at runtime | but data is correct.
I'm not sure how to best explain it so here's a video~.
The code is actually pretty easy to follow (Thanks to SolidJS's stores primitive, it's amazing). I've learned a lot of best practices with Solid since then when I picked up SolidJS in May 2024. I'm running into another roadblock that's testing my knowledge.
Anyone know how to maybe fix this? Or what the reason is? I'm already using
reconcile
. I'm thinking it's because SortableJS seems to perform updates on the DOM elements outside of SolidJS's knowledge so maybe it's just what it is?
Here's a PR on my project if you want to play around with it: https://github.com/Blankeos/car-finance-calculator/pull/1/files10 Replies
Hmm interesting so it's actually the way I update.
1. Previously: 🙁
2. Fixes the update issue (by not using reconcile). ✅
3. Interestingly this doesn't work: 🙁
---
2 is the best solution, but there's 1 last error I'm facing. Whenever I sort to the end of the list. I get this:
This is interesting: https://github.com/solidjs/solid/issues/1898#issuecomment-2333471351
GitHub
NotFoundError: Failed to execute 'insertBefore' on 'Node': The node...
Describe the bug Here's a reproducer https://github.com/Qawaz/solid-start-issue In the reproducer I've made two success samples demonstrating the same library succeeding with a little sourc...
---
Minimal Reproduction:
Solid Playground
Quickly discover what the solid compiler will generate from your JSX template
This is just my personal perspective so I could be entirely off base.
Why would you think that Sortable would work with Solid?
Solid has to own the DOM in order to manipulate it efficiently, it heavily relies on “that things are where it left them”. Sortable strikes me as a library that acts “as if it owns the DOM” and cursory inspection of the framework specific integrations seem to corroborate that, as they seem to give Sortable an intermediate, framework friendly abstraction to keep Sortable away from the DOM.
So from my perspective having both Solid and Sortable act as two masters for the same vanilla DOM is asking for trouble.
So I would be in this camp:
I'm thinking it's because SortableJS seems to perform updates on the DOM elements outside of SolidJS's knowledge so maybe it's just what it is?That may also explain why there was so little response to the Sortable comments in the PR you referenced. But as stated, that's just my take.
GitHub
GitHub - SortableJS/Sortable: Reorderable drag-and-drop lists for m...
Reorderable drag-and-drop lists for modern browsers and touch devices. No jQuery or framework required. - SortableJS/Sortable
GitHub
GitHub - SortableJS/vue.draggable.next: Vue 3 compatible drag-and-d...
Vue 3 compatible drag-and-drop component based on Sortable.js - SortableJS/vue.draggable.next
yeah, the way you're combining solid and sortablejs will not work as explained by peerrey
you might be able get around by actually resolving the nodes yourself and feeding them into a node that solid doesn't render but that requires the internal working of both libraries
Note: by using
structuredClone
you are depriving the store of referential stability of the unchanged elements thus forcing a full replacement of the DOM elements managed by the For
.
Here is a variation of your example that preserves referential stability of the elements but that shows how hopelessly confused Solid is getting. For
also supplies the index()
signal that represents the reactive index position of the rendered item
.
Drag the 4
above the 3
.
It seems Sortable is swapping the elements and then Solid is swapping them back—but the index()
reflects where Solid thinks the elements are in the list, i.e. that 4 is above 3.
Drag the 5
about the 4
.
- Based on the changes in counts
(see console) Solid then moves 5
in front of 3
.
So you end up with an index()
sequence of 0,1,4,3,2 when it should always be 0,1,2,3,4.
https://playground.solidjs.com/anonymous/026a0143-3818-4983-a772-855011f031aeSolid Playground
Quickly discover what the solid compiler will generate from your JSX template
maybe you could disable solid rendering while sortable is active and still have anything downstream reactive
Using
<For each={unwrap(counts)}>
seems to stop Solid from moving the elements. Consequently index()
is stuck with the intial order.i think the best approach is to put the nodes back in the order as solid knows it if you must actually use sortable of course
nope, only works for a few cases as solid rendering has it own array reconciliation algorithm
can't avoid implementing a subset of mapArray