Reactive field inside objects of an array
How do I achieve this (line 62)?
Basically I want a reactive field inside objects of an array which update the array itself when they change
10 Replies
How do you update
CartItem
's count?with
increment
and decrement
You could pass
Cart
to CartItem
and call .set((prev) => [...prev])
on increment/decWhich I don't want to do. The goal here is to have an intuitive api for
Cart
and CartItem
Signals are only reactive with reference updates and
createStore
doesn't make classes reactive.
You might be able to use createStore
for storing the array but I'm not familiar enough with it to help.Only reactive thing here is the
Cart
, because only it has signal. It is only reactive to change of whole array of CartItem
. If you want to have reactivity on the CartItem
's count
, then it should also be a signal (you already have increment and decrement that can be wrappers to update count
as a signal). However, then it would be only reactive to the count
only if you get it within some reactive context (like createEffect
). So cart.get()
still wouldn't react to increment / decrement
this, but cart.get()[i].getCount()
would and to the particular item (of index i
) in list. The cart.get()
would still trigger the effect if the whole array changes.
There's also another way, less granular, to "update" whole Cart
's array, when the CartItem
's count
changes. In this case CartItem
should have the concept of ownership - it should know in which Cart
it's contained in. Then, when count
changes, trigger the "update" on whole array. Or maybe just the callback when count
changes, there are probably many more ways. With callback it would be something like that:
And the onUpdate
callback should trigger the change of array, so that it triggers other updates. It can be done with copy new CartItem(id, () => { set(prev => [...prev]) })
or just reassignment, when signal's option is createSignal<Array<CartItem>>(items, { equals: false })
- just set(prev => prev)
would trigger update
The first way should be more efficient, because when you change only one item's count, only dependents on this single item's count are updated. The second will trigger updates for things that depend on the whole array, so when you change one item's count, dependents on this item's count as well as others are updated. Not to say that it's not viable solution, so just use whatever meets your needs.
And using createStore
should have same effect as the first way (basically every property is signal), with just proxy overheadThe first way is actually what is intended here
In a cart You show items individually and its enough to just react to changes of that item and not update the array itself. we only update the array when length of it changes which makes sense
The goal here is to have an intuitive api for“Intuitive” perhaps in an imperative context; but here you are working in a reactive context where read/write segregation is valued. Think of it as query/command separation where the store delivers a read-only “query” object. TheCart
andCartItem
SetStoreFunction
is then used as the building block for creating specialized, custom tailored function closures (the “commands”) that are only passed to those parts of the program which absolutely need write access (and with only just-enough write access).
It's about granting (sane) mutability more responsibly.Jessica Joy Kerr (@jessitron) on X
GOTO was evil because we asked, "how did I get to this point of execution?" Mutability leaves us with, "how did I get to this state?"
Twitter
GitHub
solid/packages/solid/store/src/store.ts at 9082a7bc6f965f8e3a97821b...
A declarative, efficient, and flexible JavaScript library for building user interfaces. - solidjs/solid
Yes but even if I use setStore as a primitive I have to wrap both
Cart
and CartItem
into another type and do some weird stuff that complicates the code unnecessarily.
Now that I thought about it more I realized that I don't need to update the Cart itself when count changes in any of the itemsA store is about data. A class instance collocates data and (possibly mutable) behaviour. What is the incentive to use a class in the first place?
Have a look at solid-todomvc—the
TodoStore
items are editable; it's not that different from a Cart.