diff --git a/.changeset/clever-ghosts-laugh.md b/.changeset/clever-ghosts-laugh.md new file mode 100644 index 000000000000..3de871ba799c --- /dev/null +++ b/.changeset/clever-ghosts-laugh.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: ensure `svelte:component` evaluates props once diff --git a/packages/svelte/src/compiler/compile/render_dom/wrappers/InlineComponent/index.js b/packages/svelte/src/compiler/compile/render_dom/wrappers/InlineComponent/index.js index 3544a759dd1e..ef7e5432d47e 100644 --- a/packages/svelte/src/compiler/compile/render_dom/wrappers/InlineComponent/index.js +++ b/packages/svelte/src/compiler/compile/render_dom/wrappers/InlineComponent/index.js @@ -436,11 +436,6 @@ export default class InlineComponentWrapper extends Wrapper { b`if (${name}) @claim_component(${name}.$$.fragment, ${claim_nodes});` ); } - if (updates.length) { - block.chunks.update.push(b` - ${updates} - `); - } const tmp_anchor = this.get_or_create_anchor(block, parent_node, parent_nodes); const anchor = has_css_custom_properties ? 'null' : tmp_anchor; const update_mount_node = has_css_custom_properties @@ -481,6 +476,7 @@ export default class InlineComponentWrapper extends Wrapper { ${name} = null; } } else if (${switch_value}) { + ${updates} ${updates.length > 0 && b`${name}.$set(${name_changes});`} } `); diff --git a/packages/svelte/test/runtime/samples/dynamic-component-evals-props-once/Comp1.svelte b/packages/svelte/test/runtime/samples/dynamic-component-evals-props-once/Comp1.svelte new file mode 100644 index 000000000000..d4fe28a8a370 --- /dev/null +++ b/packages/svelte/test/runtime/samples/dynamic-component-evals-props-once/Comp1.svelte @@ -0,0 +1,5 @@ + + +

value(1) = {value}

diff --git a/packages/svelte/test/runtime/samples/dynamic-component-evals-props-once/Comp2.svelte b/packages/svelte/test/runtime/samples/dynamic-component-evals-props-once/Comp2.svelte new file mode 100644 index 000000000000..07d41f3d8464 --- /dev/null +++ b/packages/svelte/test/runtime/samples/dynamic-component-evals-props-once/Comp2.svelte @@ -0,0 +1,5 @@ + + +

value(2) = {value}

diff --git a/packages/svelte/test/runtime/samples/dynamic-component-evals-props-once/_config.js b/packages/svelte/test/runtime/samples/dynamic-component-evals-props-once/_config.js new file mode 100644 index 000000000000..a8c94dbb8a6b --- /dev/null +++ b/packages/svelte/test/runtime/samples/dynamic-component-evals-props-once/_config.js @@ -0,0 +1,28 @@ +export default { + html: ` +

value(1) = 1

+ + `, + + async test({ assert, component, window, target }) { + const button = target.querySelector('button'); + await button.dispatchEvent(new window.Event('click')); + assert.htmlEqual( + target.innerHTML, + ` +

value(2) = 2

+ + ` + ); + assert.equal(component.n, 2); + await button.dispatchEvent(new window.Event('click')); + assert.htmlEqual( + target.innerHTML, + ` +

value(1) = 3

+ + ` + ); + assert.equal(component.n, 3); + } +}; diff --git a/packages/svelte/test/runtime/samples/dynamic-component-evals-props-once/main.svelte b/packages/svelte/test/runtime/samples/dynamic-component-evals-props-once/main.svelte new file mode 100644 index 000000000000..3a5805b3e546 --- /dev/null +++ b/packages/svelte/test/runtime/samples/dynamic-component-evals-props-once/main.svelte @@ -0,0 +1,12 @@ + + + + + +