-
-
Notifications
You must be signed in to change notification settings - Fork 4.4k
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
$derived
unexpectedly reevaluate
#15414
Comments
Mmm weirdly this doesn't happen if you actually return b for c instead of just logging...I suppose it's something that has to do with undefined (the return value of console.log) |
Returning But other simple values like BTW, It would be great to have some documentation explaining the internal mechanics of the internal implementation of Svelte's reactivity system. After all, both SolidJS and Vue provide extensive details about their inner workings. Actually, I stumbled upon this "bug" today while exploring Svelte's So I’m still really curious about how it manages to balance both behaviors. I’ve noticed that recomputation always propagates from deeper |
So i was exploring this a bit and there's definitely a bug...the problem is that since I still need to figure out the right fix tho. |
I tried playing around with the logic in for (i = 0; i < length; i++) {
dependency = dependencies[i];
var prev_version = dependency.wv;
var reaction_wv = reaction.wv;
if (dependency.wv > reaction_wv) {
dependency.wv = reaction_wv;
}
if (check_dirtiness(/** @type {Derived} */ (dependency))) {
update_derived(/** @type {Derived} */ (dependency));
} else {
dependency.wv = prev_version;
}
if (dependency.wv > reaction_wv) {
return true;
}
} This fixes the issue above, but one test now fails |
@trueadm this doesn't actually fix the issue...weirdly because i tested it before and i remember seeing it working but now i can't seem to fix it anymore. |
@paoloricciuti Yeah it doesn't for me either now. I'll revisit tomorrow lol. |
I think I've also fumbled before: in reality the reaction that has the wrong version is Still can't wrap my head around how to fix it tho |
So after digging into this more – this behaviour, whilst not ultimately desirable, is also not a bug. Deriveds today are not guaranteed to never re-run – they can in plenty of situations due to the state of the reactive graph. Given they're pure functions, they should be no issue other than doing extra work in the odd case they do over-fire. Effects should never over-fire because of the state of the reactive graph though – and in this case the effect is working fine. For us to force that the derived cannot update here means that we lose a very important facet of reactivity – in the case where you want to schedule an effect and then switch the value back to what it was before. This is very common in emulating Svelte 4 reactivity in many cases and thus changing this functionality would break too much of the ecosystem. |
Describe the bug
The reactivity system don't work as expect.
Consider the code below:
cycle
is an iterator, callingcycle()
will get 1, 2, 1, 1, then 1, 2, 1, 1, etc.a
is a$state
, and I invoke ansetInterval
to() => a = cycle()
, so thata
will be 1, 2, 1, 1 ... right?const b = $derived(a)
const c = $derived(b)
$effect
used c. Let's say$effect(() => { const _ = c }
So, the ideal results should be:
...
Right? But now in the
#4
step, b doesn't invalidate, but c invalidates.In the reporduction below, I replaced the
cycle
with a button to let you control more.And I log every
$derived
reruns by usingReproduction
https://svelte.dev/playground/a727bfaac87f41bdbe3d007f9928e5dc?version=5.20.5
Open the console and click the button 3 times.
After you clicked the 4th time, you are on the
#4
state described above.Expected output:
Actual output:
Logs
System Info
Severity
annoyance
The text was updated successfully, but these errors were encountered: