Skip to content

Commit 5497b3d

Browse files
trueadmRich-Harris
andauthored
fix: ensure all effect cleanup functions are untracked (#11567)
* fix: ensure all effect cleanup functions are untracked * add test --------- Co-authored-by: Rich Harris <[email protected]>
1 parent f6e8777 commit 5497b3d

File tree

5 files changed

+38
-0
lines changed

5 files changed

+38
-0
lines changed

.changeset/dirty-eyes-itch.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"svelte": patch
3+
---
4+
5+
fix: ensure all effect cleanup functions are untracked

packages/svelte/src/internal/client/reactivity/effects.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {
33
current_component_context,
44
current_effect,
55
current_reaction,
6+
current_untracking,
67
destroy_effect_children,
78
dev_current_component_function,
89
execute_effect,
@@ -14,6 +15,7 @@ import {
1415
set_is_destroying_effect,
1516
set_is_flushing_effect,
1617
set_signal_status,
18+
set_untracking,
1719
untrack
1820
} from '../runtime.js';
1921
import {
@@ -295,11 +297,14 @@ export function execute_effect_teardown(effect) {
295297
var teardown = effect.teardown;
296298
if (teardown !== null) {
297299
const previously_destroying_effect = is_destroying_effect;
300+
const previous_untracking = current_untracking;
298301
set_is_destroying_effect(true);
302+
set_untracking(true);
299303
try {
300304
teardown.call(null);
301305
} finally {
302306
set_is_destroying_effect(previously_destroying_effect);
307+
set_untracking(previous_untracking);
303308
}
304309
}
305310
}

packages/svelte/src/internal/client/runtime.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,11 @@ export function set_is_destroying_effect(value) {
4848
is_destroying_effect = value;
4949
}
5050

51+
/** @param {boolean} value */
52+
export function set_untracking(value) {
53+
current_untracking = value;
54+
}
55+
5156
// Used for $inspect
5257
export let is_batching_effect = false;
5358
let is_inspecting_signal = false;
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import { test } from '../../test';
2+
3+
// nothing to test here — if the teardown function is not untracked, effect will loop
4+
export default test({});
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<script>
2+
let prop = $state();
3+
let key = $state({});
4+
5+
function action() {
6+
prop = {};
7+
$effect.pre(() => {
8+
return () => {
9+
prop;
10+
}
11+
});
12+
}
13+
14+
$effect(() => key = {});
15+
</script>
16+
17+
{#key key}
18+
<div use:action>test</div>
19+
{/key}

0 commit comments

Comments
 (0)