From 00819509e5612a34bf7457cd67d8c1c9619d6054 Mon Sep 17 00:00:00 2001 From: Hari Date: Thu, 28 Aug 2025 19:59:25 +0100 Subject: [PATCH] fix: properly clean up component lifecycle order issue - move effect cleanup to happen before new creation in key function - ensure proper lifecycle order. destroy old component -> create new component - so now the order is script -> mount -> abort -> destroy -> script -> mount --- .changeset/chilled-donkeys-ring.md | 5 +++++ .../svelte/src/internal/client/dom/blocks/key.js | 13 ++++++++----- 2 files changed, 13 insertions(+), 5 deletions(-) create mode 100644 .changeset/chilled-donkeys-ring.md diff --git a/.changeset/chilled-donkeys-ring.md b/.changeset/chilled-donkeys-ring.md new file mode 100644 index 0000000000..d77bd092c4 --- /dev/null +++ b/.changeset/chilled-donkeys-ring.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: fixed component lifecycle timing issue in #key blocks. its now properly cleaned up before new instance are created. diff --git a/packages/svelte/src/internal/client/dom/blocks/key.js b/packages/svelte/src/internal/client/dom/blocks/key.js index 5e3c42019f..74e8a613c3 100644 --- a/packages/svelte/src/internal/client/dom/blocks/key.js +++ b/packages/svelte/src/internal/client/dom/blocks/key.js @@ -25,7 +25,7 @@ export function key(node, get_key, render_fn) { /** @type {V | typeof UNINITIALIZED} */ var key = UNINITIALIZED; - /** @type {Effect} */ + /** @type {Effect | null} */ var effect; /** @type {Effect} */ @@ -37,10 +37,6 @@ export function key(node, get_key, render_fn) { var changed = is_runes() ? not_equal : safe_not_equal; function commit() { - if (effect) { - pause_effect(effect); - } - if (offscreen_fragment !== null) { // remove the anchor /** @type {Text} */ (offscreen_fragment.lastChild).remove(); @@ -54,6 +50,12 @@ export function key(node, get_key, render_fn) { block(() => { if (changed(key, (key = get_key()))) { + // Pause and cleanup the old effect before creating a new one + // This ensures proper component lifecycle ordering (destroy -> create -> mount) + if (effect) { + pause_effect(effect); + effect = null; + } var target = anchor; var defer = should_defer_append(); @@ -63,6 +65,7 @@ export function key(node, get_key, render_fn) { offscreen_fragment.append((target = create_text())); } + // Create the new effect with the component pending_effect = branch(() => render_fn(target)); if (defer) {