From 0480f040c0f220dc090a263e81cfcd4a8db9737f Mon Sep 17 00:00:00 2001 From: Simon H <5968653+dummdidumm@users.noreply.github.com> Date: Mon, 11 Aug 2025 20:41:34 +0200 Subject: [PATCH] fix: skip effects inside dynamic component that is about to be destroyed (#16601) * fix: skip effects inside dynamic component that is about to be destroyed When a dynamic component was updated to a different instance and its props were updated at the same time, effects inside the component were still called with the already-changed props. The fix is to mark the branch as skipped to never got to those effects. Fixes #16387 * undo accidental commit --- .changeset/neat-files-do.md | 5 +++++ .../client/dom/blocks/svelte-component.js | 4 +++- .../svelte-component-props-update/Comp-1.svelte | 7 +++++++ .../svelte-component-props-update/Comp-2.svelte | 1 + .../svelte-component-props-update/_config.js | 11 +++++++++++ .../svelte-component-props-update/main.svelte | 16 ++++++++++++++++ 6 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 .changeset/neat-files-do.md create mode 100644 packages/svelte/tests/runtime-runes/samples/svelte-component-props-update/Comp-1.svelte create mode 100644 packages/svelte/tests/runtime-runes/samples/svelte-component-props-update/Comp-2.svelte create mode 100644 packages/svelte/tests/runtime-runes/samples/svelte-component-props-update/_config.js create mode 100644 packages/svelte/tests/runtime-runes/samples/svelte-component-props-update/main.svelte diff --git a/.changeset/neat-files-do.md b/.changeset/neat-files-do.md new file mode 100644 index 0000000000..ddba170c78 --- /dev/null +++ b/.changeset/neat-files-do.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: skip effects inside dynamic component that is about to be destroyed diff --git a/packages/svelte/src/internal/client/dom/blocks/svelte-component.js b/packages/svelte/src/internal/client/dom/blocks/svelte-component.js index f16da9c427..2697722b39 100644 --- a/packages/svelte/src/internal/client/dom/blocks/svelte-component.js +++ b/packages/svelte/src/internal/client/dom/blocks/svelte-component.js @@ -62,8 +62,10 @@ export function component(node, get_component, render_fn) { if (defer) { offscreen_fragment = document.createDocumentFragment(); offscreen_fragment.append((target = create_text())); + if (effect) { + /** @type {Batch} */ (current_batch).skipped_effects.add(effect); + } } - pending_effect = branch(() => render_fn(target, component)); } diff --git a/packages/svelte/tests/runtime-runes/samples/svelte-component-props-update/Comp-1.svelte b/packages/svelte/tests/runtime-runes/samples/svelte-component-props-update/Comp-1.svelte new file mode 100644 index 0000000000..fdafa27c3c --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/svelte-component-props-update/Comp-1.svelte @@ -0,0 +1,7 @@ + + +{#each data.obj.arr as i} +

{i}

+{/each} \ No newline at end of file diff --git a/packages/svelte/tests/runtime-runes/samples/svelte-component-props-update/Comp-2.svelte b/packages/svelte/tests/runtime-runes/samples/svelte-component-props-update/Comp-2.svelte new file mode 100644 index 0000000000..e345a7697c --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/svelte-component-props-update/Comp-2.svelte @@ -0,0 +1 @@ +

Comp 2

\ No newline at end of file diff --git a/packages/svelte/tests/runtime-runes/samples/svelte-component-props-update/_config.js b/packages/svelte/tests/runtime-runes/samples/svelte-component-props-update/_config.js new file mode 100644 index 0000000000..ff5ca12dbf --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/svelte-component-props-update/_config.js @@ -0,0 +1,11 @@ +import { flushSync } from 'svelte'; +import { test } from '../../test'; + +export default test({ + async test({ assert, target }) { + const [btn] = target.querySelectorAll('button'); + btn.click(); + flushSync(); + assert.htmlEqual(target.innerHTML, `

Comp 2

`); + } +}); diff --git a/packages/svelte/tests/runtime-runes/samples/svelte-component-props-update/main.svelte b/packages/svelte/tests/runtime-runes/samples/svelte-component-props-update/main.svelte new file mode 100644 index 0000000000..abd785fff3 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/svelte-component-props-update/main.svelte @@ -0,0 +1,16 @@ + + + + +