derived, but update-able, signal?
is it possible to have a piece of reactive code that can be updated directly, but is also tied to another piece of state?
I have a list I fetch from server that is wrapped with createAsync. I want to use this to track server state, but then have a dup of that list that can be updated any number of times in the app. The user then hits save, and we update the list on server and revalidate
I originally just tried a derived signal, but I can't directly update this. Then I was thinking of just making another signal and having it's initial value be a call to its initial value, but I'm not sure if this is a good thing to do
any idea?
26 Replies
createWritableMemo from solid primitives should do what you want
This is also how createSignal might work in solid 2
could you expand on the second part? i will probably use the writableMemo, thank you
should i be worried about memo'ing this if it's not a very intensive operation though?
nah since you need to store a copy of the data anyway to overwrite yourself
in solid 2 createSignal may allow something like this
oh interesting
so it tracks for reactive updates in the scope passed to createSignal?
yeah
that would be neat
it's kind of a weird situation moving from react -> solid because a lot of things behave more naturally, but then a small handful of things that are super ergonomic in react feel harder in solid because everything doesn't get torn down and rerendered
not actually sure if this is one of those situations now that i think of it, but i built this same app in react and didn't run into this for whatever reason
iiirc react's advice for writable derived state is to setState during render right?
I probably was doing it wrong tbh
now i'm thinking back, i think my server state was in react-query, and i passed it as initial props to another piece of state, so i'd have client state in the hook, and then cache from RQ. Then when RQ updated the state would reset back to initialState from RQ
update: don't think
createWritableMemo
plays well when derived from a createAsync 🙃
Which I guess sort of makes sense for some reasonit evaluates eagerly so if you want to use Suspense you need to place it above where you call it, rather than below
idk if that's your issue or not
I call it in a parent and pass it to a child, which lives inside a suspense
although, even if i don't pass it down, the presence of it in my component seems to defer rendering
I have to try and trim down this code, 1 sec
yeah bc it evaluates inside the component you call it in, not where you use it, that's the 'eagerly'
oh
when you said i need to place it above, i thought you meant the memo, not the suspense
ah nah sorry
i understand
oof this isn't very fun, so there's no way for me to use it as lifted state essentially, if i need it where i have it now i'll need context i think ?
something like that, lazy memos are tricky atm
so just so i can understand properly, what is it about this that the eager evaluation that defers the render of the whole component ?
suspense is triggered by accessing the async value. usually that would happen inside jsx so you can use a suspense in the same component, but memos access the async value in the component body, so the suspense needs to be above the whole component
oh so in this case, the suspense i'm using can't track that it's been accessed
i still don't get why it holds up the whole component, is that just default behavior for createAsync then ?
it's specifically because the async value is being called inside a memo, and thus inside the component body. you can think of it like this
as soon as
asyncValue
gets called it looks up the ownership chain for a suspense and activates itand since there's no suspense above, there's no fallback, and nothing to show
if there isn't one there then yeah
yea I guess i can like sort of avoid it by just wrapping parent layout with suspense, but i get a really awkwardly brief blank page before the suspense i actually designed for in my current component kicks in
you should be able to force the response to be paused by setting
deferStream
on the createAsync
i think suspending in the layout is probably a bad idea
then i get different behaviors on navigation vs refresh, i assume because in one case the layout is re-run, in the other case it's not
oh yea deferStream just fixes everythng
for the most part at least
i'll work for first load at least
on page reload i see nothing, but on client nav i get my suspended ui
nvm i'm stupid and i was testing on a new page i made for debugging 🤦♂️. this is a tomorrow problem, not a 3 am problem