Skip to content

Commit

Permalink
fix: ensure all effect cleanup functions are untracked (#11567)
Browse files Browse the repository at this point in the history
* fix: ensure all effect cleanup functions are untracked

* add test

---------

Co-authored-by: Rich Harris <rich.harris@vercel.com>
  • Loading branch information
trueadm and Rich-Harris committed May 12, 2024
1 parent f6e8777 commit 5497b3d
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .changeset/dirty-eyes-itch.md
@@ -0,0 +1,5 @@
---
"svelte": patch
---

fix: ensure all effect cleanup functions are untracked
5 changes: 5 additions & 0 deletions packages/svelte/src/internal/client/reactivity/effects.js
Expand Up @@ -3,6 +3,7 @@ import {
current_component_context,
current_effect,
current_reaction,
current_untracking,
destroy_effect_children,
dev_current_component_function,
execute_effect,
Expand All @@ -14,6 +15,7 @@ import {
set_is_destroying_effect,
set_is_flushing_effect,
set_signal_status,
set_untracking,
untrack
} from '../runtime.js';
import {
Expand Down Expand Up @@ -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);
}
}
}
Expand Down
5 changes: 5 additions & 0 deletions packages/svelte/src/internal/client/runtime.js
Expand Up @@ -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;
Expand Down
@@ -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}

0 comments on commit 5497b3d

Please sign in to comment.