component doesnt react to changes in state
I've got a component that has a state
collaborators
which holds an array of objects.
The problem is that when this state is modified, through setCollaborators
function, the component does not update for the new value.
why is this happenin, and how can I work around this issue?
29 Replies
My guess is that the values inside
collection.collaborators
are updating, but the array itself isn't changing - signals only cause updates when their whole value changes. setcurrentCollaborators([...collection!.collaborators])
might do the trick.
Though with that said, I don't think this is a good use of signals and effects. createMemo
would be a better fit here, since all you're really doing here is deriving currentCollection
and currentCollaborators
from your store and route params. That would eliminate any signal update problems anyway since you'd be referencing the original store.spreading the values have not helped either 🤔 I dont understand why it doesnt react to the change.
In what way would
createMemo
help with this issue? Could you please show an example
I noticed something... the state "currentCollaborators" is not changing, but the store itself does change 🤔
For some reason the state's value isnt changing 😩Memos for this case are just more in-line with how Solid works, since
currentCollection
is just derived from your store + router state. There’s plenty of examples out there on using memos, I can’t provide any rnAfter using:
The value does change, however the JSX component doesnt re-render
const currentCollaborators = createMemo(() => [...currentCollection()?.collaborators])
maybe?this didn't help either, doesn't update at all now
Did you make
currentCollection
a memo as well?no, that one is in effect atm
I'll try memo, one moment
😩 no luck:
weird weird, does the value of
currentCollaborators
change as expected?no it remains same length
Could it have to do with deep objects in store?
maybe? Does the collection get modified after
params
is changed?
you could try to unwrap
on the collection
return in currentCollection
return unwrap(collection)
what is the purpose of unwrap
to remove the proxy on store objects and give you the raw value
this works, but why
My guess is that something is changing the collection after this code runs causing the
coll.collaborators
to be changed. Since currentCollection
returns an store proxy of an object in the store, accessing a property inside that object causes currentCollaborators
to track that nested property for any changes.
I think an alternative is to use untrack
this is confusing, what is proxy? This did work with other parts of store, when for example creating a signal and having it's value retrieved from store
A proxy basically intercepts read/write to an object. Stores use proxies to help with creating their nested reactivity by creating a signal for a property when accessed.
For example, if I do
store.firstName
somewhere in my code for the first time, the store will create a signal for that firstName
property and call it's getter to give you the value. So if you were using this in an effect:
the effect would now be tracking firstName
.
For each level down you go (store.flashcards.collections
), it is a proxy that connects to a signal. So accessing that property in an effect will subscribe that effect to the property.
In your case, collection
is an object in either store.flashcards.collections
or store.flashcards.sharedCollections
. collection.collaborators
will be subscribed to in the memo because collaborators
is a proxy connected to a signal.
I hope this makes some sense. I'm not the best at explaining the core concepts, but hope it helpsI understand what you mean, Im somewhat familiar with the fact that createEffect listens to some dependency like
store.flashcards.collections
. what confuses me is whether having called .find(...)
to retrieve the desired collection broken some part of that reactivity tracking mechanism. Does the dependency have to be accessed directly as a.b.c.d
rather than d = a.b.c.find(...)
in order for the component to notice changes? 🤔I think
.find(...)
should still track because it accesses the values inside itself like when you do collection.id === params.collection_id
, id
of each collection
in store.flashcards.collections is being tracked.
It's hard to say without looking at the code, but there might be something that was modifying the collection's collaborators
somewherecollaborators are only updated in store's setState call, where some new collaborator object is added. ( each property is destructured all the way to the collaborators list ), would you like to see
sure
Oki one moment
this is the only part that modifies collaborators array
when does this get run?
Also, when you said it works, does it update the JSX too?
yes it finally updates the component new values are being rendered on screen as expected
it is executed when a collaborator is added to the collection, an event fires and calls store's function to update collaborators
button add collaborator -> event -> store.addCollaborator(...)
progress nonethe less thank you a lot sir Reeeee 😁
Nice
it is time to lay down, brain is fried short circuit
I couldn't explain the issue completely but glad it works
🫡 take a break
It is alright, you have given me enough insight to continue working on it further and read some more about the magic of solid
thank you veri much