Skip to content

Commit 873a184

Browse files
authored
fix: ensure each key validation occurs for updates (#12836)
* fix: ensure each key validation occurs for updates * fix: ensure each key validation occurs for updates
1 parent 555e90f commit 873a184

File tree

4 files changed

+65
-21
lines changed

4 files changed

+65
-21
lines changed

.changeset/tame-dodos-float.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'svelte': patch
3+
---
4+
5+
fix: ensure each key validation occurs for updates

packages/svelte/src/internal/client/validate.js

Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -45,28 +45,30 @@ export function validate_dynamic_component(component_fn) {
4545
* @returns {void}
4646
*/
4747
export function validate_each_keys(collection, key_fn) {
48-
const keys = new Map();
49-
const maybe_array = untrack(() => collection());
50-
const array = is_array(maybe_array)
51-
? maybe_array
52-
: maybe_array == null
53-
? []
54-
: Array.from(maybe_array);
55-
const length = array.length;
56-
for (let i = 0; i < length; i++) {
57-
const key = key_fn(array[i], i);
58-
if (keys.has(key)) {
59-
const a = String(keys.get(key));
60-
const b = String(i);
61-
62-
/** @type {string | null} */
63-
let k = String(array[i]);
64-
if (k.startsWith('[object ')) k = null;
65-
66-
e.each_key_duplicate(a, b, k);
48+
render_effect(() => {
49+
const keys = new Map();
50+
const maybe_array = collection();
51+
const array = is_array(maybe_array)
52+
? maybe_array
53+
: maybe_array == null
54+
? []
55+
: Array.from(maybe_array);
56+
const length = array.length;
57+
for (let i = 0; i < length; i++) {
58+
const key = key_fn(array[i], i);
59+
if (keys.has(key)) {
60+
const a = String(keys.get(key));
61+
const b = String(i);
62+
63+
/** @type {string | null} */
64+
let k = String(array[i]);
65+
if (k.startsWith('[object ')) k = null;
66+
67+
e.each_key_duplicate(a, b, k);
68+
}
69+
keys.set(key, i);
6770
}
68-
keys.set(key, i);
69-
}
71+
});
7072
}
7173

7274
/**
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { flushSync } from 'svelte';
2+
import { test } from '../../test';
3+
4+
export default test({
5+
compileOptions: {
6+
dev: true
7+
},
8+
9+
test({ assert, target }) {
10+
let button = target.querySelector('button');
11+
12+
button?.click();
13+
14+
assert.throws(flushSync, /each_key_duplicate/);
15+
}
16+
});
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<script>
2+
let data = [
3+
[0, 0],
4+
[0, 4],
5+
[1, 4],
6+
];
7+
8+
function add() {
9+
const n = [0, 0]
10+
data.push(n);
11+
data = data;
12+
}
13+
</script>
14+
15+
<button onclick={add}>add</button>
16+
17+
<ul>
18+
{#each data as d (d.join(""))}
19+
<li> {d}</li>
20+
{/each}
21+
</ul>

0 commit comments

Comments
 (0)