-
-
Notifications
You must be signed in to change notification settings - Fork 4.3k
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
Reused element binding (bind:this
) updates to null
long after destruction
#11920
Comments
bind:this
) to null
after destructionbind:this
) to null
long after destruction
This is fixed in Svelte 5. Because this is a real edge case I'm tempted to say we're not going to backport this. |
@dummdidumm I disagree. I'm sorry for such a convoluted test case (I didn't have enough time to test out more possibilities), but here's a much simpler and probably a more believable situation: I'd argue that reusing element bindings, although maybe uncommon, shouldn't be considered an edge case. |
bind:this
) to null
long after destructionbind:this
) updates to null
long after destruction
Actually this seems to be not fixed in svelte5, at least not in production builds ( Here is an example showing it not working: use the select box to switch to component D and then back to some other (A, B or C) and look into the browser console to see how a null value is set. This might be the place where the null value is set: But I am not sure why it only happens in production builds. I opened a separate issue for svelte 5: |
Describe the bug
This might be too convoluted, see the REPL for a better explanation.
A component, after being destroyed, retains its bindings to the elements inside (via
bind:this={element}
). This wouldn't be a problem, but:then the component's
element
will be updated after the element has been destroyed and shouldn't have any rights to do so.The 1st condition happens if the element has a outro transition. After the transition is done, the component schedules a binding callback via its
{tag}_binding
function. If, at this point, any update happens in the component, the destroyed element will update its binding with the component, which is unexpected behavior, since after the element is destroyed it shouldn't cause any updates in its component.In the REPL, I proposed a solution, which may or may not be what Svelte needs. In short, it will replace the
{tag}_binding
function with:X
is replaced by the element name. This code should be in thebind_this.js
file on lines 29 and 80. I, unfortunately, haven't figured out how to make theX_binding_active
variable named like that, because acorn spaghettifies its name 😅.Anyway, to recap:
You need an element, which: 1) has a outro transition on itself or one of its children, 2) has a
bind:this
bindingAnd you need to 1) destroy the element, 2) update the component ($$invalidate) after the transition has played.
Edit: as I realized, you don't need multiple components
Reproduction
https://svelte.dev/repl/b1160a5db49943ac88bde30323cea348?version=4.2.17
Reproduction and even a possible solution inside the REPL (though duplicated here)
Edit: A much simpler test case can be found here.
There doesn't have to be an {#each}, i think, but this just serves as an example of why this bug can be disastrous.
Sorry if I overstated the Severity field below, by the way.
Logs
No response
System Info
Severity
application-breaking
The text was updated successfully, but these errors were encountered: