how to avoid child component re-creation with For
I have a store that is a list of tuples: each tuple is like ["type as string", { item, props }].
One of these items contains a value that I want to change like a controlled input, with a 'value' and a 'setValue' prop.
The problem is that when I call "setStore" to update the item value, the entire tuple is a new tuple with the changed value, it's not the same old tuple with the value mutated in place.
I use the <For> component to render this store list. AFAIU, when the For sees a new tuple, it removes the old <div> created by my component and recreates it all over again.
How can I have a store that is a list of tuples and change one value in this tuple without Solid re-creating my child components all the time ?
4 Replies
This page[0] in particular says that Solid "strongly recommends immutable patterns"
[0] https://www.solidjs.com/tutorial/stores_mutation
SolidJS
Solid is a purely reactive library. It was designed from the ground up with a reactive core. It's influenced by reactive principles developed by previous libraries.
how to reconcile immutable patterns with For ?
I just tried using the 'setStore' call to mutate the object and return the same old tuple, but now the child component is not updated
I guess it sees the same object and assumes the element is already up-to-date
From what I saw in the solid docs, there's not much examples that uses a lot of components
many reactivity examples render everything in only one component
so it's hard to figure out how to make this work with subcomponents
hmmm....
it appears that the secret is how you use the setStore function
you cannot call setStore() and return a object with the changed value
you must use each parameter of setStore() to walk down the path to the property you want to change
instead of setStore( item => item.id === id, obj => { ...obj, valueToChange } )
you should call setStore( item => item.id === od, "valueToChange", valueToChange )
In this way, setStore knows exactly what has changed and can update it accordingly
the setStore docs is not very explicit with this and some people (like me) are very used to the patterns used by diffing frameworks
also this is not typechecking right to me (at least in vscode, in which TS is very fragile to me using win10 with wsl (also with every project, not just Solid))
When I pass the "valueToChange" string key of the property, TS complains that it "is not assignable to parameter of type 'never'."
you can use
reconcile
helper to apply immutable changes as mutable to stores and then you can use <For>
to rely on stable references
but if you prefer to keep your data immutable, and push reconciliation to the rendering instead, you can use <Key>
instead of <For>
https://github.com/solidjs-community/solid-primitives/tree/main/packages/keyed#keyVery nice, thanks! Will check it out