Granular update of store array doesn't trigger effects depending on the whole array
I am really puzzled with proper setup for store array management.
I am creating the array in the store:
And updating elements in it (important: I can not update the whole array):
But neither of these effects are triggered:
Why these effects are not triggered and how to fix it?
Demo: https://stackblitz.com/edit/solidjs-store-array-1?file=src%2FApp.tsx
UPD: funny that individual points effect is working in SolidJS playround: https://playground.solidjs.com/anonymous/6e486319-8488-4651-82d2-15a7602e7afa
14 Replies
You are likely looking for
trackStore
.
Roughly, store's fine-grained reactivity doesn't re-run when something inside changes; it re-runs when the thing you directly accessed changes.I think I understand why effect based on whole array is not fired - because the reference to whole array stays the same.
But why effect for each element is not fired too? Are the elements not signals?
That's because you set an object, not a primitive, so x and y are not directly set.
You could also change updatePoint to do the following:
That would be reactive.
Or alternatively,
setStore('points', i, ['x', 'y'], () => Math.random() * 200 + 20)
.@Alex Lohr It doesn't seem to work. Effects are not fired.
https://stackblitz.com/edit/solidjs-store-array-1-acf9yv?file=src%2FApp.tsx
You need to reference x and y in the effects directly for it to fire.
Or use the trackStore primitive, as Peer suggested.
Ok, thanks!
Funny that individual points effect is working in SolidJS playround:
https://playground.solidjs.com/anonymous/6e486319-8488-4651-82d2-15a7602e7afa
Since you're setting those individual points, that's to be expected.
It's usually simpler to wrap the setter instead of creating effects to track every single store change.
It is the same code as in https://stackblitz.com/edit/solidjs-store-array-1?file=src%2FApp.tsx, and as in my local setup, and this effect is not triggered there, only in solidjs playground.
It is the most cryptic part for me - why if I change individual point in the array, effect that depends on this individual point is not fired.
why if I change individual point in the array, effect that depends on this individual point is not fired.I wouldn't be surprised if it's an inherent limitation of proxies. While Arrays are objects, I find that proxied Arrays are far from perfect.
That's true, unfortunately, especially for sparse arrays.
this behavior of
store merging top-level object properties
surprises a lot of folks combined with the fact that solid playground's log has implicit deep tracking. both the old docs and new docs mention this but missing the other side of the whole story. we probably need an explainer of what gets triggered
.
also there's no limitation on what get triggered from reactivity standpoint. it's just a choice made solely for performance.
this merging behavior can also be exploited to get the behavior op want
to repeat, this thread's title is the whole point of solid and what solid is capable of.
So I imagine this exists so that multiple
key
: value
s can be set with a single set
operation; I didn't realize that was an option; thank You!Where can I see documentation for this access syntax?
The docs mention the shallow merging behavior.
{ [i]: { } }
part is just JS
i.e Object.assign({}, { [key]: value })