Difference between `setState` and `produce`?
I have
appState
as a store, and I'm trying to pass appState.selectedTable
as a prop to a child component. When I simply use setAppState
, it doesn't trigger a prop change in the child component. I've found that I need to use produce
for it to work. The problem is, the documentation only gives a one-liner about the produce
API. Could someone provide more information on how to properly use produce
and createStore
in this context?6 Replies
produce
is a pattern that comes from immer
.
The appState
you receive as an argument is not the actual state, but a proxy. With immer
each mutation is caught with the proxy and translated into an immutable data change, with solid
it's similar, but then with a signal-store instead of immutable data.
That being said, the first li
should work too afaict.It doesn't in my case though and I still don't know why. The usage:
If u could make reproducible example in solid's playground I can have a look at it
I've been trying for a while and it seems impossible to make a reproducible code but this is the closest I can get:
https://playground.solidjs.com/anonymous/ef126951-8ad2-4aa6-ac89-91bd1b40fb0b
With this code the
createEffect
in the child component is registered and fired correctly (mine is not). But if you cycle through the buttons they behave weirdly. The first button you click will have its state changed when you click other buttons, my app also behaves like this. Maybe this is closely related to the problem.Solid Playground
Quickly discover what the solid compiler will generate from your JSX template
jaja. these references to keys of a store within a store. I remember I had difficulties with it at some point too. My solution back then was to do
setStore({selectedTable: table})
. I agree the default behaviour is indeed a bit unexpected.
once you do setStore("selectedTable", table)
this setStore("selectedTable", ...)
becomes equivalent to setStore("tables", index-of-table, ...)
I think it's the same principle why for example
this also worksit's because of the merging behaviour of the store setter
initially when it's
undefined
it sets selectedTable
to table
, but afterwards it's an object so it mutates the existing object (which is also stored elsewhere as table.something
, which also gets mutated), instead of replacing the existing object as you might expect
or if it helps setStore
basically does this (in this specific case):