diff --git a/CHANGELOG.md b/CHANGELOG.md index 3dd0aadf8b64..8cdc334868a3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## Unreleased * In `vars` array, correctly indicate whether `module` variables are `mutated` or `reassigned` ([#3215](https://github.com/sveltejs/svelte/issues/3215)) +* Fix spread props not updating in certain situations ([#3521](https://github.com/sveltejs/svelte/issues/3521), [#4480](https://github.com/sveltejs/svelte/issues/4480)) * In `dev` mode, check for unknown props even if the component has no writable props ([#4323](https://github.com/sveltejs/svelte/issues/4323)) * Exclude global variables from `$capture_state` ([#4463](https://github.com/sveltejs/svelte/issues/4463)) * Fix bitmask overflow for slots ([#4481](https://github.com/sveltejs/svelte/issues/4481)) diff --git a/src/compiler/compile/render_dom/wrappers/InlineComponent/index.ts b/src/compiler/compile/render_dom/wrappers/InlineComponent/index.ts index 28b3c938f9d3..8088bbac91a8 100644 --- a/src/compiler/compile/render_dom/wrappers/InlineComponent/index.ts +++ b/src/compiler/compile/render_dom/wrappers/InlineComponent/index.ts @@ -224,7 +224,9 @@ export default class InlineComponentWrapper extends Wrapper { const condition = dependencies.size > 0 && (dependencies.size !== all_dependencies.size) ? renderer.dirty(Array.from(dependencies)) : null; + const unchanged = dependencies.size === 0; + let change_object; if (attr.is_spread) { const value = attr.expression.manipulate(block); initial_props.push(value); @@ -233,13 +235,20 @@ export default class InlineComponentWrapper extends Wrapper { if (attr.expression.node.type !== 'ObjectExpression') { value_object = x`@get_spread_object(${value})`; } - changes.push(condition ? x`${condition} && ${value_object}` : value_object); + change_object = value_object; } else { const obj = x`{ ${name}: ${attr.get_value(block)} }`; initial_props.push(obj); - - changes.push(condition ? x`${condition} && ${obj}` : x`${levels}[${i}]`); + change_object = obj; } + + changes.push( + unchanged + ? x`${levels}[${i}]` + : condition + ? x`${condition} && ${change_object}` + : change_object + ); }); block.chunks.init.push(b` diff --git a/test/runtime/samples/spread-component-2/Widget.svelte b/test/runtime/samples/spread-component-2/Widget.svelte new file mode 100644 index 000000000000..ae27aeb5e531 --- /dev/null +++ b/test/runtime/samples/spread-component-2/Widget.svelte @@ -0,0 +1,13 @@ + + +
foo: {foo}
+baz: {baz} ({typeof baz})
+qux: {qux}
+quux: {quux}
+selected: {selected}
diff --git a/test/runtime/samples/spread-component-2/_config.js b/test/runtime/samples/spread-component-2/_config.js new file mode 100644 index 000000000000..6d36e8e60dfb --- /dev/null +++ b/test/runtime/samples/spread-component-2/_config.js @@ -0,0 +1,76 @@ +export default { + props: { + list: [{ + foo: 'lol', + baz: 40 + 2, + qux: 5, + quux: 'core' + }, { + foo: 'lolzz', + baz: 50 + 2, + qux: 1, + quux: 'quuxx' + }], + }, + + html: ` +foo: lol
+baz: 42 (number)
+qux: 0
+quux: core
+selected: true
+foo: lolzz
+baz: 52 (number)
+qux: 0
+quux: quuxx
+selected: false
+foo: lol
+baz: 43 (number)
+qux: 0
+quux: heart
+selected: true
+foo: lolzz
+baz: 53 (number)
+qux: 0
+quux: heartxx
+selected: false
+foo: lol
+baz: 43 (number)
+qux: 1
+quux: heart
+selected: false
+foo: lolzz
+baz: 53 (number)
+qux: 1
+quux: heartxx
+selected: true
+