Derrived Signal With A Ressource
Hi!
That might be an easy one.
I get a resource from a Context called userData.
What is the proper way to derrive further signals or just values from it? The following example doesn´t seem correct and I think it smells.
const {userData: [user]} = useAuth("");
// When the component renders, user is not defined yet.
const [userInitials, setUserInitials] = createSignal<string>("");
createEffect(() => {
if(user.state === "ready") {
// as soon user is there, I set the initials-signal.
setUserInitials(user().firstName.slice(0, 1) + user().lastName.slice(0, 1));
}
})
5 Replies
Something like
See also derived signals and
createMemo
.
The important thing to remember is that the JSX returned by a component exists within an implicit reactive scope which is sufficient for a derived signal to subscribe to its dependencies.
So if userInitials
is just used once in the returned JSX then a derived signal is more than enough. However each access will re-run the entire derived signal. Again, not a big deal if the derived signal isn't doing anything complicated.
However once you pass it as a prop where it may be accessed who-knows-how-many-times, wrapping it in a createMemo
is probably a good idea. The memo will then only rerun the function whenever one of the dependencies change, itself always returning the value of the latest run.
If you want to stay away from non-null assertion operators then just write it like this:
The verbosity is a concession to the fact that TypeScript treats Accessor
s as functions rather than get
ters which don't tend to change value during synchronous execution of a script.MDN Web Docs
get - JavaScript | MDN
The get syntax binds an object property to a function that will be called when that property is looked up. It can also be used in classes.
Thanks a lot for your great responses! That´s definitly what I was searching for. 🙂
Okey, but to take it further:
In this case, I´m loosing my Setter-Function for the userInitials (Just as an example, I know, I don´t really need a stter for user-initials).
What, if I want to initialize a Signal with the user() as soon it is not null anymore, but then set the new Signal independently again? Let´s say f.e. for a controlled inputField?
See: https://discord.com/channels/722131463138705510/722131463889223772/1335413663368220712
With
createWritableMemo
you can specify an initial value. Then in the effect function you just keep the previous value if user()
is undefined
.
In general:
- you only use the setter when you temporarily "know better" but
- you still want to update based on the primary dependency but only if it updates after you set it.
afaik: Solid 2.x signals will simply work that way; follow the dependencies, over-rideable via setter.Very interesting!, what Ryan writes in his blog post! That createWritableMemo will save me a lot of uneccessary unpredicatable code i think. Thank you sir!