diff --git a/.changeset/silly-lies-film.md b/.changeset/silly-lies-film.md new file mode 100644 index 000000000000..4fa473f6f617 --- /dev/null +++ b/.changeset/silly-lies-film.md @@ -0,0 +1,5 @@ +--- +"svelte": patch +--- + +fix: child effects are removed from parent branches diff --git a/packages/svelte/src/internal/client/reactivity/deriveds.js b/packages/svelte/src/internal/client/reactivity/deriveds.js index dd31cc154bb3..18cb4031faab 100644 --- a/packages/svelte/src/internal/client/reactivity/deriveds.js +++ b/packages/svelte/src/internal/client/reactivity/deriveds.js @@ -70,19 +70,22 @@ export function derived_safe_equal(fn) { * @returns {void} */ function destroy_derived_children(signal) { + var effects = signal.effects; + // TODO: should it be possible to create effects in deriveds given they're meant to be pure? - if (signal.effects) { - for (var i = 0; i < signal.effects.length; i += 1) { - destroy_effect(signal.effects[i]); - } + if (effects !== null) { signal.effects = null; + for (var i = 0; i < effects.length; i += 1) { + destroy_effect(effects[i]); + } } + var deriveds = signal.deriveds; - if (signal.deriveds) { - for (i = 0; i < signal.deriveds.length; i += 1) { - destroy_derived(signal.deriveds[i]); - } + if (deriveds !== null) { signal.deriveds = null; + for (i = 0; i < deriveds.length; i += 1) { + destroy_derived(deriveds[i]); + } } } diff --git a/packages/svelte/src/internal/client/reactivity/effects.js b/packages/svelte/src/internal/client/reactivity/effects.js index 680bef6a0d0f..2e61cb407242 100644 --- a/packages/svelte/src/internal/client/reactivity/effects.js +++ b/packages/svelte/src/internal/client/reactivity/effects.js @@ -237,11 +237,22 @@ export function destroy_effect(effect) { remove(effect.dom); } + var parent = effect.parent; + + if (parent !== null && (effect.f & BRANCH_EFFECT) !== 0) { + var effects = parent.effects; + if (effects !== null) { + var index = effects.indexOf(effect); + effects.splice(index, 1); + } + } + effect.effects = effect.teardown = effect.ctx = effect.dom = effect.deps = + effect.parent = // @ts-expect-error effect.fn = null; diff --git a/packages/svelte/src/internal/client/runtime.js b/packages/svelte/src/internal/client/runtime.js index 27c8f82f0a8d..f5c250931984 100644 --- a/packages/svelte/src/internal/client/runtime.js +++ b/packages/svelte/src/internal/client/runtime.js @@ -353,11 +353,13 @@ export function remove_reactions(signal, start_index) { * @returns {void} */ export function destroy_children(signal) { - if (signal.effects) { - for (var i = 0; i < signal.effects.length; i += 1) { - destroy_effect(signal.effects[i]); - } + var effects = signal.effects; + + if (effects !== null) { signal.effects = null; + for (var i = 0; i < effects.length; i += 1) { + destroy_effect(effects[i]); + } } }