How to sync two different signals inside a store maybe
I have an array and an index to the array defined separately as two signals, here I've demonstrated:
.
Now when I update the array for example reset it, the cursor still shows the old location which causes an out of bounds error. How do I structure my code to prevent this kind of issue, and still be able to have a computation to access inside the array reactively.
https://playground.solidjs.com/anonymous/f3de692a-5ace-4a08-a51c-dc8541ec0b85
Solid Playground
Quickly discover what the solid compiler will generate from your JSX template
26 Replies
I wouldn't prefer to use a batch to whenever the array changes just reset the cursor along with it. Because the array is not a simple signal it's computed from other different signals, for example I filter an unrelated stuff to reconstruct this array.
maybe like this 👉
?
https://playground.solidjs.com/anonymous/df57c303-5ec5-4fcd-b6ca-9143f55a1765
Solid Playground
Quickly discover what the solid compiler will generate from your JSX template
I just wonder if there is a pattern to keep two signals in a consistent sync state based on some constrained relationship with each other.
because you see i never intended the cursor to point to dangled reference in the array.
whenever the array changes I want to reset the cursor back to zero
that way the fail_computation would never fail or be undefined, because I know array always has at least one element and when array changes and cursor resets back to zero, fail_computation still always references something.
I just can't do that in a batch, because array is derived from another computation that is hard to control when it is set.
There will be a new primitive in solid 2.0:
createProjection
Solid.js v2
Rough WIP docs for Solid 2.0.
I am confused by what state._active is doing, is that some internal flag to indicate something changing.
That primitive should help with derived values inside stores.
I think
._active
is like your .cursor
And If I can simultaneously set more than one property inside that projection then I can both calculate the derived array and set the cursor to 0 at the same time which should be a solution to my problem.
._active is never used so I don't understand it's meaning.
The example could be a bit more intuitive, sure. But I hope you can zoom out and see the full picture and how it relates to your problem.
for now, you could do something like this where you
try/catch
inside the memo and set the cursor to 0 if it fails. or you could do something like this where you compare the cursor with the array-length inside the memo and reset the cursor to 0 if the cursor exceeds the length.Solid Playground
Quickly discover what the solid compiler will generate from your JSX template
Solid Playground
Quickly discover what the solid compiler will generate from your JSX template
it's generally not adviced to set signals inside memos, but rules are there to be bended
note that I add a default item to the array in the array-memo to assure there will always be 1 item in the array.
you could also have a conditional in a getter of
cursor
like this.
it's a pity that you can not do const [store, setStore] = createSignal({ get signal() { return signal() }, set signal(value){ setSignal(value) }})
. I would have expected that to work, but once you do setStore('signal', 'some-value')
it seems to break the setter/getter.Solid Playground
Quickly discover what the solid compiler will generate from your JSX template
aa nvm, that's not the best approach because then it would mean that once the array becomes large enough again it would jump back to the original cursor. you do want to reset the cursor-signal like this
Solid Playground
Quickly discover what the solid compiler will generate from your JSX template
In solidjs real world example here: https://github.com/solidjs/solid-realworld/blob/main/src/store/index.js#L18
The store has a articles getter (no setter) but still later can be set to other values. Also the getter tracks the changes so it can set itself reactively as well.
Here's my example: https://playground.solidjs.com/anonymous/5ba79d4f-cd7f-470b-a8ef-cbf475aee207
In my example this throws an error when I try to set the property that has only a getter. Not sure If I am missing something but how does that work in the real world example, I am wondering.
Solid Playground
Quickly discover what the solid compiler will generate from your JSX template
GitHub
solid-realworld/src/store/index.js at main · solidjs/solid-realworld
A Solid Implementation of the Realworld Example App - solidjs/solid-realworld
Here's an example place where "articles" is set to custom value https://github.com/solidjs/solid-realworld/blob/main/src/store/createArticles.js#L45
GitHub
solid-realworld/src/store/createArticles.js at main · solidjs/soli...
A Solid Implementation of the Realworld Example App - solidjs/solid-realworld
oof that code is rough 😅 mutating that actions-object everywhere... pre-typescript mindsets
i think the way this works is that in
you are not actually setting the
store.articles
but you are setting store.articles[slug]
.
but then when you look in what createArticle
returns, store.articles
is a resource. so not sure how that works.
confusing codebase that realworld exampleSolid Playground
Quickly discover what the solid compiler will generate from your JSX template
I will add one more possible pattern
https://playground.solidjs.com/anonymous/95ffaec3-b169-406c-ba4b-c8d4b7e5758b
Solid Playground
Quickly discover what the solid compiler will generate from your JSX template
True. I wish we could mock
createProjection
too. Can not wait tbh.
(createWritableMemo
is how solid 2.0 createSignal
will work)"Everytime the array changes, cursor needs to reset to 0, then a few seconds later go to 1". It's like a preview of the 0 index then it transitions to show 1 index."
what does this mean?
That's what I wanted to do.
then you don't really need "sync".
you want to detect array change.
set the index to 0 and with a timer set it to 1 ?
yes, I can probably easily do that with a createEffect, but before the effect runs after the array changes some memos can show dangling pointers. That's why I mentioned "sync"
1. well probably not easily, you still need to consider the case the array changes again before the timer
2. if you look at my example, you can see that this memo is self guarding.
Ok I will try it thanks.
Could you recommend me an example repo demonstrating async resources shared state and separation of actions vs state and things like that, like a real world example.
mm, no sorry, I don't really have any recommendations for u. @davedbase do u maybe have an idea?