fix: only update lazy properties that have actually changed (#10415)

* fix: only update lazy properties that have actually changed

* code golf

* changeset

* Add test
pull/10409/head
Dominic Gannaway 11 months ago committed by GitHub
parent 9aa0ed3eb6
commit f9f5d3a1be
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,5 @@
---
"svelte": patch
---
fix: only update lazy properties that have actually changed

@ -786,10 +786,20 @@ export function get_first_element(block) {
* @returns {void} * @returns {void}
*/ */
function update_each_item_block(block, item, index, type) { function update_each_item_block(block, item, index, type) {
const block_v = block.v;
if ((type & EACH_ITEM_REACTIVE) !== 0) { if ((type & EACH_ITEM_REACTIVE) !== 0) {
set_signal_value(block.v, item); set_signal_value(block_v, item);
} else if (is_lazy_property(block.v)) { } else if (is_lazy_property(block_v)) {
block.v.o[block.v.p] = item; // If we have lazy properties, it means that an array was used that has been
// proxied. Given this, we need to re-sync the old array by mutating the backing
// value to be the latest value to ensure the UI updates correctly. TODO: maybe
// we should bypass any internal mutation checks for this?
const o = block_v.o;
const p = block_v.p;
const prev = o[p];
if (prev !== item) {
o[p] = item;
}
} }
const transitions = block.s; const transitions = block.s;
const index_is_reactive = (type & EACH_INDEX_REACTIVE) !== 0; const index_is_reactive = (type & EACH_INDEX_REACTIVE) !== 0;

@ -0,0 +1,7 @@
<script>
let { array } = $props();
</script>
{#each array as number}
<p>{number}</p>
{/each}

@ -0,0 +1,14 @@
import { test } from '../../test';
export default test({
async test({ assert, target }) {
const [b1] = target.querySelectorAll('button');
b1.click();
await Promise.resolve();
assert.htmlEqual(
target.innerHTML,
'<button>add</button><p>1</p><p>2</p><p>3</p><p>4</p><p>0</p>'
);
}
});

@ -0,0 +1,13 @@
<script>
import Child from './Child.svelte';
let array = $state([1,2,3,4]);
const addNew = () => {
array.push(0)
}
</script>
<button onclick={addNew}>add</button>
<Child {array} />
Loading…
Cancel
Save