Skip to content

Commit 1fbcbbb

Browse files
committed
fix: cleanup non-branch effects created inside block effects
1 parent 6534f50 commit 1fbcbbb

File tree

4 files changed

+54
-0
lines changed

4 files changed

+54
-0
lines changed

.changeset/eleven-humans-kneel.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: cleanup non-branch effects created inside block effects

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

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,22 @@ export function destroy_effect_children(signal, remove_dom = false) {
418418
}
419419
}
420420

421+
/**
422+
* @param {Effect} signal
423+
* @returns {void}
424+
*/
425+
export function destroy_block_effect_children(signal) {
426+
var effect = signal.first;
427+
428+
while (effect !== null) {
429+
var next = effect.next;
430+
if ((effect.f & BRANCH_EFFECT) === 0) {
431+
destroy_effect(effect);
432+
}
433+
effect = next;
434+
}
435+
}
436+
421437
/**
422438
* @param {Effect} effect
423439
* @returns {void}
@@ -445,6 +461,8 @@ export function update_effect(effect) {
445461
try {
446462
if ((flags & BLOCK_EFFECT) === 0) {
447463
destroy_effect_children(effect);
464+
} else {
465+
destroy_block_effect_children(effect);
448466
}
449467

450468
execute_effect_teardown(effect);
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { flushSync } from 'svelte';
2+
import { test } from '../../test';
3+
4+
export default test({
5+
async test({ assert, target, instance, logs }) {
6+
const button = target.querySelector('button');
7+
assert.deepEqual(logs, ['effect', 1]);
8+
flushSync(() => {
9+
button?.click();
10+
});
11+
assert.deepEqual(logs, ['effect', 1, 'clean', 1, 'effect', 2]);
12+
}
13+
});
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<script>
2+
let count = $state(1);
3+
function track(value){
4+
let val = value;
5+
$effect(() => {
6+
console.log("effect", val);
7+
return ()=>{
8+
console.log("clean", val);
9+
}
10+
});
11+
return value;
12+
}
13+
</script>
14+
15+
{#if track(count)}
16+
{/if}
17+
18+
<button onclick={()=> count++}></button>

0 commit comments

Comments
 (0)