fix: ensure all effect cleanup functions are untracked (#11567)

* fix: ensure all effect cleanup functions are untracked

* add test

---------

Co-authored-by: Rich Harris <rich.harris@vercel.com>
pull/11571/head
Dominic Gannaway 5 months ago committed by GitHub
parent f6e87772cb
commit 5497b3d0bc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,5 @@
---
"svelte": patch
---
fix: ensure all effect cleanup functions are untracked

@ -3,6 +3,7 @@ import {
current_component_context,
current_effect,
current_reaction,
current_untracking,
destroy_effect_children,
dev_current_component_function,
execute_effect,
@ -14,6 +15,7 @@ import {
set_is_destroying_effect,
set_is_flushing_effect,
set_signal_status,
set_untracking,
untrack
} from '../runtime.js';
import {
@ -295,11 +297,14 @@ export function execute_effect_teardown(effect) {
var teardown = effect.teardown;
if (teardown !== null) {
const previously_destroying_effect = is_destroying_effect;
const previous_untracking = current_untracking;
set_is_destroying_effect(true);
set_untracking(true);
try {
teardown.call(null);
} finally {
set_is_destroying_effect(previously_destroying_effect);
set_untracking(previous_untracking);
}
}
}

@ -48,6 +48,11 @@ export function set_is_destroying_effect(value) {
is_destroying_effect = value;
}
/** @param {boolean} value */
export function set_untracking(value) {
current_untracking = value;
}
// Used for $inspect
export let is_batching_effect = false;
let is_inspecting_signal = false;

@ -0,0 +1,4 @@
import { test } from '../../test';
// nothing to test here — if the teardown function is not untracked, effect will loop
export default test({});

@ -0,0 +1,19 @@
<script>
let prop = $state();
let key = $state({});
function action() {
prop = {};
$effect.pre(() => {
return () => {
prop;
}
});
}
$effect(() => key = {});
</script>
{#key key}
<div use:action>test</div>
{/key}
Loading…
Cancel
Save