Skip to content

Commit d802c3b

Browse files
authored
in spread, distinguish never-updating and always-updating props (#4487)
1 parent 3a37de3 commit d802c3b

File tree

5 files changed

+114
-3
lines changed

5 files changed

+114
-3
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
## Unreleased
44

55
* In `vars` array, correctly indicate whether `module` variables are `mutated` or `reassigned` ([#3215](https://github.com/sveltejs/svelte/issues/3215))
6+
* Fix spread props not updating in certain situations ([#3521](https://github.com/sveltejs/svelte/issues/3521), [#4480](https://github.com/sveltejs/svelte/issues/4480))
67
* In `dev` mode, check for unknown props even if the component has no writable props ([#4323](https://github.com/sveltejs/svelte/issues/4323))
78
* Exclude global variables from `$capture_state` ([#4463](https://github.com/sveltejs/svelte/issues/4463))
89
* Fix bitmask overflow for slots ([#4481](https://github.com/sveltejs/svelte/issues/4481))

src/compiler/compile/render_dom/wrappers/InlineComponent/index.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,9 @@ export default class InlineComponentWrapper extends Wrapper {
224224
const condition = dependencies.size > 0 && (dependencies.size !== all_dependencies.size)
225225
? renderer.dirty(Array.from(dependencies))
226226
: null;
227+
const unchanged = dependencies.size === 0;
227228

229+
let change_object;
228230
if (attr.is_spread) {
229231
const value = attr.expression.manipulate(block);
230232
initial_props.push(value);
@@ -233,13 +235,20 @@ export default class InlineComponentWrapper extends Wrapper {
233235
if (attr.expression.node.type !== 'ObjectExpression') {
234236
value_object = x`@get_spread_object(${value})`;
235237
}
236-
changes.push(condition ? x`${condition} && ${value_object}` : value_object);
238+
change_object = value_object;
237239
} else {
238240
const obj = x`{ ${name}: ${attr.get_value(block)} }`;
239241
initial_props.push(obj);
240-
241-
changes.push(condition ? x`${condition} && ${obj}` : x`${levels}[${i}]`);
242+
change_object = obj;
242243
}
244+
245+
changes.push(
246+
unchanged
247+
? x`${levels}[${i}]`
248+
: condition
249+
? x`${condition} && ${change_object}`
250+
: change_object
251+
);
243252
});
244253

245254
block.chunks.init.push(b`
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<script>
2+
export let foo;
3+
export let baz;
4+
export let qux;
5+
export let quux;
6+
export let selected;
7+
</script>
8+
9+
<p>foo: {foo}</p>
10+
<p>baz: {baz} ({typeof baz})</p>
11+
<p>qux: {qux}</p>
12+
<p>quux: {quux}</p>
13+
<p>selected: {selected}</p>
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
export default {
2+
props: {
3+
list: [{
4+
foo: 'lol',
5+
baz: 40 + 2,
6+
qux: 5,
7+
quux: 'core'
8+
}, {
9+
foo: 'lolzz',
10+
baz: 50 + 2,
11+
qux: 1,
12+
quux: 'quuxx'
13+
}],
14+
},
15+
16+
html: `
17+
<div>
18+
<p>foo: lol</p>
19+
<p>baz: 42 (number)</p>
20+
<p>qux: 0</p>
21+
<p>quux: core</p>
22+
<p>selected: true</p>
23+
<p>foo: lolzz</p>
24+
<p>baz: 52 (number)</p>
25+
<p>qux: 0</p>
26+
<p>quux: quuxx</p>
27+
<p>selected: false</p>
28+
</div>
29+
`,
30+
31+
test({ assert, component, target }) {
32+
component.list = [{
33+
foo: 'lol',
34+
baz: 40 + 3,
35+
qux: 8,
36+
quux: 'heart'
37+
}, {
38+
foo: 'lolzz',
39+
baz: 50 + 3,
40+
qux: 8,
41+
quux: 'heartxx'
42+
}];
43+
44+
assert.htmlEqual(target.innerHTML, `
45+
<div>
46+
<p>foo: lol</p>
47+
<p>baz: 43 (number)</p>
48+
<p>qux: 0</p>
49+
<p>quux: heart</p>
50+
<p>selected: true</p>
51+
<p>foo: lolzz</p>
52+
<p>baz: 53 (number)</p>
53+
<p>qux: 0</p>
54+
<p>quux: heartxx</p>
55+
<p>selected: false</p>
56+
</div>
57+
`);
58+
59+
component.qux = 1;
60+
61+
assert.htmlEqual(target.innerHTML, `
62+
<div>
63+
<p>foo: lol</p>
64+
<p>baz: 43 (number)</p>
65+
<p>qux: 1</p>
66+
<p>quux: heart</p>
67+
<p>selected: false</p>
68+
<p>foo: lolzz</p>
69+
<p>baz: 53 (number)</p>
70+
<p>qux: 1</p>
71+
<p>quux: heartxx</p>
72+
<p>selected: true</p>
73+
</div>
74+
`);
75+
}
76+
};
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<script>
2+
import Widget from './Widget.svelte';
3+
4+
export let list;
5+
export let qux = 0;
6+
</script>
7+
8+
<div>
9+
{#each list as item, index (item.foo)}
10+
<Widget {...item} qux={qux} selected={qux === index} />
11+
{/each}
12+
</div>

0 commit comments

Comments
 (0)