Tagged Template Literals - Why is unwrapped props value reactive?
The docs at https://github.com/solidjs/solid/tree/main/packages/solid/html indicate that reactive variables must be manually wrapped when using tagged template literals, yet this basic example still works,
https://playground.solidjs.com/anonymous/45f46e73-ac35-4455-a03b-f8501027fe23
Clarification: I am referring to line 25. It is unwrapped yet is still reactive.
I was just curious, why is this?
Expected behavior: Label2 shouldn't be reactive.
Actual behavior: Label2 is reactive.
GitHub
solid/packages/solid/html at main Β· solidjs/solid
A declarative, efficient, and flexible JavaScript library for building user interfaces. - solidjs/solid
Solid Playground
Quickly discover what the solid compiler will generate from your JSX template
29 Replies
Change it to
and see what happens
https://codepen.io/peerreynders/pen/eYoaoXV?editors=0010
The example passes props to the component as unwrapped functions, not wrapped functions.
Clarification: I was referring to line 25. It is unwrapped yet is still reactive. (updated my question)
![No description](https://cdn.answeroverflow.com/1235487190142943283/image.png)
NOTE: There is even a warning to wrap it, but it actually still works. And, I thought this was very interesting and was curious about what was happening here.
![No description](https://cdn.answeroverflow.com/1235487668578816000/image.png)
It's re-executing the component, which also causes all the html-elements to be created again on each prop change.
it would be the same as
This also 'works' in the same sense as your example: it will be reactive, because the component re-executes on every props.value change. But it will also re-create a div-element everytime.
see https://playground.solidjs.com/anonymous/8e54e752-52d6-4e34-8d83-bb9d1c335655
Solid Playground
Quickly discover what the solid compiler will generate from your JSX template
I was referring to line 25I was aware of that. I pointed out where your example deviated from the instructions. https://github.com/solidjs/solid/tree/main/packages/solid/html#readme
count
is a signal and increment
a derived value. Both of them are passed as unwrapped functions.
Your example passes a function that returns the unwrapped function (unnecessarily).
Back to the instructions about wrapping:
Observations:
1. It's a <div>
, a leaf node, so reactive values can't be passed down any further this is where the value they represent actually needs to appear.
2. firstName() + lastName()
composes two values (presumably this is what βreactive expressionβ means). This needs to be wrapped in a function.
3. props.id
is usually a getter for a primitive value, not a function. So for the whole subscription mechanic to work it needs to be wrapped in a function.GitHub
solid/packages/solid/html at main Β· solidjs/solid
A declarative, efficient, and flexible JavaScript library for building user interfaces. - solidjs/solid
Without looking at the source code the rule seems to be if something is a function βrun it to get the value out of it and subscribe for further changesβ (perhaps even recursively).
-
firstName() + lastName()
isn't a function so we need to turn it into one.
- props.id
isn't a function (and doesn't return one) so we need to turn it into one to get the value out of it.
In your code
with () => count
you somehow managed to deliver a function via props.value
which by the rules hypothesized would be run.
If you would have followed the instructions by the letter you should have written
Which results in exactly the behaviour that the instructions predicted.
The other potential issue was that you were using a "no-build" approach in a "build" playground which may mysteriously "fix" certain errors (which wasn't the case here; but that is why I chose codepen, not the playground).It's re-executing the componentWhat am I missing? https://playground.solidjs.com/anonymous/bf76951c-7041-4886-a775-8f23cf186125
Solid Playground
Quickly discover what the solid compiler will generate from your JSX template
oops ur right, i was too fast w my answer
with () => count you somehow managed to deliver a function via props.value which by the rules hypothesized would be run.this is the correct explanation: they are in fact wrapped, but done at the props-level instead of inside the template.
I'm not intimately familiar with the source code; I just wondered if I needed to adjust my mental model.
no i think u were spot on!
"Blind chicken" and all that π
@peerreynders ahhh, I see what you were doing now. Yes, line 25 indeed does not work as I originally hypothesized after changing the way the prop is passed in. π
I assumed that a getter, in itself, was still a "reactive expression" and hence needed to be wrapped.
But, I suppose that is not the case!
Also, @bigmistqke, my impression was that Solid doesn't re-render entire components. Are there exceptions to this? π
Also, @peerreynders, in the example you presented with props.id, if props.id is a getter, isn't a getter (to a primitive value) still a function?
I think it's odd that a signal getter doesn't have to be wrapped, yet when a props value is assigned a signal getter, it has to be wrapped. Strange to me...
I think it's fair to say that I have a gap in my knowledge about reactivity. π€
^
I'm also foregoing using build tools which may complicate things a bit (for learning purposes) (typescript is certainly useful for productivity, but I'm also a bit of a vanilla purist at heart π).
PS thanks for the examples π appreciated!
if props.id is a getter, isn't a getter (to a primitive value) still a function?https://www.typescriptlang.org/play/?#code/FAYw9gdgzgLgBDAhgJwOYFN4F44G9hxwbwCWAJgBQCU+hhymArshHAOQAqAEgBoCMfAMwAONgG4CcAL7ApE0JChgANugB0ysKgowAngAd0YAGYIUxNeSpi4AeltwARLGQkIqR8AXR4AC0QQZKrIcDi0RJg65pgANHD6yGD6cQwg6CQAbujIVHiS9EwsZmiYANoJSQC6EoRSMbLy4D7xifqhcBDoAO5wAAqJAB66USUwcf6BwdZeTUqqGlo6BkamFfqWZNZ2Ds4wru6OQA
TS Playground - An online editor for exploring TypeScript and JavaS...
The Playground lets you write TypeScript or JavaScript online in a safe and sharable way.
I think it's odd that a signal getter doesn't have to be wrapped,It doesn't have to be wrapped when you are passing it as a prop; it's simply the means to acquire (and subscribe) to the value; in that sense it's like a callback. When you need the actual value that it represents you need to wrap it: a) to get the value to do something with b) to subscribe to any changes that may be happening later to the value.