Subscribe to any unknown store change

Hi. Is there a way to subscribe to a store change in unknown property? I have a store:
type StoreValue = Record<string, number>;

const [store, setStore] = createStore<StoreValue>({
a: 0,
b: 0,
});
type StoreValue = Record<string, number>;

const [store, setStore] = createStore<StoreValue>({
a: 0,
b: 0,
});
And sometimes I modify it
<button type="button" onClick={() => setStore("a", undefined)}>
setStore("a", undefined)
</button>
<button type="button" onClick={() => setStore("a", undefined)}>
setStore("a", undefined)
</button>
And I want to render it's unwrapped value on each change (and I don't know the change upfront)
<div>
⚠️ store - not updating because store is not reactive - only its values:{" "}
{JSON.stringify(unwrap(store))}
</div>
<div>
⚠️ store - not updating because store is not reactive - only its values:{" "}
{JSON.stringify(unwrap(store))}
</div>
How to make the store value reactive to unknown changes?
22 Replies
bigmistqke
bigmistqke2y ago
this is currently not possible, the advice given is to wrap setStore instead. Something like
const [store, _setStore] = createStore();
const setStore = (...args: any[]) => {
// ... do some stuff
_setStore(...args)
}
const [store, _setStore] = createStore();
const setStore = (...args: any[]) => {
// ... do some stuff
_setStore(...args)
}
nirtamir2
nirtamir2OP2y ago
Thanks! If I want to subscribe to unknown keys I think it's better to solve it by wrapping the store value in some object. Meaning: Instead of
type StoreValue = Record<string, number>;

const [store, setStore] = createStore<StoreValue>({
a: 0,
b: 0,
});
type StoreValue = Record<string, number>;

const [store, setStore] = createStore<StoreValue>({
a: 0,
b: 0,
});
Doing
type StoreValue = {value: Record<string, number>};

const [store, setStore] = createStore<StoreValue>({value:{
a: 0,
b: 0,
}});
type StoreValue = {value: Record<string, number>};

const [store, setStore] = createStore<StoreValue>({value:{
a: 0,
b: 0,
}});
Then I can do
{JSON.stringify(unwrap(store.value))}
{JSON.stringify(unwrap(store.value))}
Is it considered a best practice?
bigmistqke
bigmistqke2y ago
I don't think it makes a difference. This strategy of JSON.stringifying the store to trigger an effect will work, but there is a cost to JSON.stringify. It's not the most optimal way, the most optimal way rn would be to wrap the setter instead. as an aside, you do not need unwrap either. JSON.stringify(store) will be equivalent to JSON.stringify(unwrap(store)) afaik.
nirtamir2
nirtamir2OP2y ago
I try my suggestion - and it did not work I wonder why
bigmistqke
bigmistqke2y ago
if u could make a minimal reproduction in the playground, i can look at it
nirtamir2
nirtamir2OP2y ago
Yes
bigmistqke
bigmistqke2y ago
something specific u have questions about?
nirtamir2
nirtamir2OP2y ago
Yes - How make the <div>{JSON.stringify(unwrap(store.value))}</div> reactive I mean - I want it to change JSON.strinfigy(unwrap(store.value)) when value.a changes without knowing upfront that value.a changed (value["unknown")
bigmistqke
bigmistqke2y ago
ok don't unwrap i guess unwrap untracks the reactive value
nirtamir2
nirtamir2OP2y ago
You right! Thank you!
bigmistqke
bigmistqke2y ago
yes, i don't think u ever really need to use unwrap tbh u can just work w the proxy directly ur welcome!
nirtamir2
nirtamir2OP2y ago
Actually this seems resonable (unwrap inside effect does not track the dependency)
bigmistqke
bigmistqke2y ago
a didn't know that, never really touched it. only use it if i want cleaner debug-log to get rid of the proxy-clutter.
thetarnav
thetarnav2y ago
ryansolid
CodeSandbox
Observing State - CodeSandbox
Observing State by ryansolid using babel-preset-solid, object-observer, solid-js
nirtamir2
nirtamir2OP2y ago
Thanks! Now I created another demo that confused me a bit Is JSON.stringify(store) reactive? Not that I removed the unwrap (my mistake for it sorry) it seems that store value is updated
nirtamir2
nirtamir2OP2y ago
@bigmistqke @thetarnav Sorry - my mistake - store is reactive. Meaning that if store.a changes - store changes too so it's jsx / effect will rerun. I infer it by looking at this codesandbox I created: https://codesandbox.io/p/sandbox/solidjs-reactivity-context-reactive-store-setter-eccv7z?file=%2Fsrc%2FApp.tsx&selection=%5B%7B%22endColumn%22%3A10%2C%22endLineNumber%22%3A16%2C%22startColumn%22%3A10%2C%22startLineNumber%22%3A16%7D%5D
solidjs reactivity - context reactive - store setter
CodeSandbox is an online editor tailored for web applications.
bigmistqke
bigmistqke2y ago
that's neat what is the question?
nirtamir2
nirtamir2OP2y ago
No question. Just clarification to myself and other that will look at this in the future Thanks for the help 🙂
bigmistqke
bigmistqke2y ago
ur welcome 👍
aryzing
aryzing14mo ago
By any chance would you know how to correctly type the aliased setStore with Typescript? When typed as below, the type of the args is never, which throws errors in the existing setters,
function setStateAndDoStuff(...args: Parameters<typeof setState>) {
setState(args);
doStuff(state);
}
function setStateAndDoStuff(...args: Parameters<typeof setState>) {
setState(args);
doStuff(state);
}
bigmistqke
bigmistqke14mo ago
there is StoreSetter from solid-js/store
Want results from more Discord servers?
Add your server