Skip to content
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

fix: avoid disconnecting deriveds that are still active #13292

Merged
merged 8 commits into from
Sep 17, 2024
Merged

Conversation

trueadm
Copy link
Contributor

@trueadm trueadm commented Sep 17, 2024

Fixes #13284.

This was an interesting bug. This was historically dealt with by having multiple effects for this – we'd have one for the condition and one for the actual handling of the branching. That's because the dependencies for effects are only realised after we execute the inner function. Normally this is fine, but if you synchronously add/remove effects during this, it can cause the current effect to not correctly attach its current dependencies.

One way of tackling this is to instead wrap the condition in a derived, which are more lightweight than effects. I originally did that in this PR but the instead adjusted the logic for determining how we disconnect a derived reaction – and instead we avoid disconnection if the derived is in our active reaction's dependencies.

Copy link

changeset-bot bot commented Sep 17, 2024

🦋 Changeset detected

Latest commit: f63e493

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
svelte Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@trueadm
Copy link
Contributor Author

trueadm commented Sep 17, 2024

I also applied it to key block as it looks to work exactly like the if block logic does.

@Rich-Harris
Copy link
Member

Not sure I understand how pausing a branch affects the block's dependencies — isn't that a bug?

@trueadm
Copy link
Contributor Author

trueadm commented Sep 17, 2024

Not sure I understand how pausing a branch affects the block's dependencies — isn't that a bug?

Nope. It's by design. Let's take:

State A: true
State B: false

Derived C = B

If Effect: A || C
Inner Effect: {A} {C}

The If Effect starts by not having a dependency on C, only the Inner Effect does. When we switch A off, the If Effect then reads A and C, but its not store in its dependencies till the end, in the mean time it also destroys Inner Effect which is depending on A and C. Now given the fact that we haven't yet associated the If Effect with C, the removal of the Inner Effect will detach Derived C from State B. When we associate If Effect with C, it will be too late, we will already have removed it from B.

I can see if there's an alternative solution for this.

@trueadm
Copy link
Contributor Author

trueadm commented Sep 17, 2024

Okay, so I found an alternative angle – we avoid disconnecting derived signals that are in the the current new_deps. This seems like a less expensive change.

@trueadm trueadm changed the title fix: ensure the if block condition is wrapped in a derived fix: avoid disconnecting deriveds that are still active Sep 17, 2024
Co-authored-by: Rich Harris <rich.harris@vercel.com>
@trueadm trueadm merged commit 09527fd into main Sep 17, 2024
9 checks passed
@trueadm trueadm deleted the derived-if branch September 17, 2024 21:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Reactivity breaks on derived if condition (Svelte 5)
2 participants