fix: ensure proxied array length is updated (#9782)

* fix: ensure proxied array length is updated

* fix: ensure proxied array length is updated

* add test

* lint
pull/9791/head
Dominic Gannaway 1 year ago committed by GitHub
parent 10aacfa603
commit f1954d034b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,5 @@
---
'svelte': patch
---
fix: ensure proxied array length is updated

@ -139,23 +139,34 @@ const handler = {
target[READONLY_SYMBOL] = value;
return true;
}
const metadata = target[STATE_SYMBOL];
const s = metadata.s.get(prop);
if (s !== undefined) set(s, proxy(value));
const is_array = metadata.a;
const not_has = !(prop in target);
if (metadata.a && prop === 'length') {
if (is_array && prop === 'length') {
for (let i = value; i < target.length; i += 1) {
const s = metadata.s.get(i + '');
if (s !== undefined) set(s, UNINITIALIZED);
}
}
if (!(prop in target)) increment(metadata.v);
if (not_has) {
increment(metadata.v);
}
// @ts-ignore
target[prop] = value;
// If we have mutated an array directly, we might need to
// signal that length has also changed too.
if (is_array && not_has) {
const ls = metadata.s.get('length');
const length = target.length;
if (ls !== undefined && ls.v !== length) {
set(ls, length);
}
}
return true;
},

@ -0,0 +1,9 @@
import { flushSync } from 'svelte';
import { test } from '../../test';
export default test({
skip_if_ssr: 'permanent',
html: `
<input><input><input><div>3</div>
`
});

@ -0,0 +1,10 @@
<script>
let values = $state(['foo', 'bar', 'baz']);
let elements = $state([]);
let nums = $state([1,2,3]);
</script>
{#each values as value, i}
<input bind:this={elements[i]} bind:value={values[i]} />
{/each}
<div>{elements.length}</div>
Loading…
Cancel
Save