-
-
Notifications
You must be signed in to change notification settings - Fork 4.5k
Svelte 5: value in template becomes unreactive under seemingly random circumstances #11012
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Markup reactivity triggered by implicitly called methods isn't and won't be properly supported: see #9860. Regarding your REPL, it seems P.S.: to maintainers: I'm kinda surprised that |
@7nik Okay, I see this ticket is a duplicate of #9860, the one that you created. However, I don't understand the reasoning of Conduitry in his response to your ticket.
Why? I don't understand the problem. Seriously why? Look, the fact of the matter is that because Svelte chooses to intentionally make it impossible to pass a Or of course, we can recreate those primitives, but then we have to deviate in our API design from Svelte's API design. Suddenly, we need to create So in any case, I was hoping that at least, I could create a
These small things can just help to reduce any visual noise when reading code and therefor are important to people like me. Again, it would be even better if Svelte would just allow the community to create our own primitives that have the exact same ergonomics as Svelte's native runes, but I'm skeptical that that's ever gonna happen. |
My understanding: to support this feature, almost any You can destructure $derived to make reactive primitives: example (ignore |
Yeah, well, I disagree. Because the additional overhead would be a one-time overhead on the very first render. After that, if the underlying variable is indeed non-reactive, then it won't ever re-render anyway and so then there's no additional overhead.
Ah damn, if it wasn't for that editNever mind, I saw the issue you just opened about this and it does indeed look like a bug. |
As I said, the overhead may be critical during the hydration — when a user sees a rendered page but isn't reactive yet. When this phase becomes long enough for the user to try to interact with the page, but nothing happens, it leads to a negative and confusing experience. Maybe the team measured the overhead, maybe not, IDK. |
We shouldn't assume that everything is reactive due to perf reasons, therefore closing. |
Describe the bug
Well, the best way I can describe the bug is by showing you. This will take at most 3 minutes of your time.
https://youtu.be/4JdoGHOIY4k
In short, since I know that Svelte uses a
stringify()
function in itsrender_effect()
functions for its templates, which looks like this:I know that if I have anything that's not a string (e.g. an object), but that can be casted to a string (e.g. if it has a
toString()
method), then it can be used in Svelte 5 templates plainly and Svelte'sstringify()
function will make sure it's casted to a string. I'm experimenting with how this can enable me to create objects and / or functions that "just work" in templates. So far it always worked well, but this time it stops working, but only under very specific circumstances. Watch the video to see what I mean.Reproduction
Here is the REPL, so you can play around with it.
But I really recommend you watch the video to see when things go wrong in the template and stop being reactive.
Logs
System Info
Severity
annoyance
Edit
I now see that depending on what line I uncomment / active, the generated output code changes dramatically.
When my increment function looks like this:
Then the generated output code looks like this:
But when my increment function looks like this:
Then the generated output code looks like this:
Notice how suddenly Svelte doesn't bother generating
$.mutate()
or$.get()
code in the increment function anymore? Even though that shouldn't even be necessary anyway... And notice howtext_2
has been taken out of therender_effect()
? That's clearly why it stopped being reactive. But why Svelte would make these choices is beyond me...Edit 2
The only thing I can guess, is that for some reason Svelte concludes that when I use
count(count + 1)
(orcount(count() + 1)
I've also tried), that the plaincount
cannot by reactive. Probably because it thinks that functions cannot be reactive. But since functions can in fact be adapted to have a[Symbol.toPrimitive]()
method attached to them and therefor can be casted to a string which could reactively call some kind of inner state, I would recommend that Svelte stops assuming functions cannot be reactive.Because also, the cost of being wrong in that scenario, is negligible. If you indeed create a
render_effect()
like so:And it turns out that
count
is indeed a plain function that produces no reactive output when it's casted to a string, then you've lost nothing, because then thatrender_effect()
will never run a second time...The text was updated successfully, but these errors were encountered: