Skip to content

Commit 8a1cf83

Browse files
Stricter key clash detection. Fixes #12691 (#12837)
1 parent c15f1e1 commit 8a1cf83

File tree

2 files changed

+21
-5
lines changed

2 files changed

+21
-5
lines changed

src/Components/Components/src/RenderTree/RenderTreeDiffBuilder.cs

+4-5
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,10 @@ private static void AppendDiffEntriesForRange(
9999
if (oldKey != null || newKey != null)
100100
{
101101
#region "Get diff action by matching on key"
102+
// Regardless of whether these two keys match, since you are using keys, we want to validate at this point that there are no clashes
103+
// so ensure we've built the dictionary that will be used for lookups if any don't match
104+
keyedItemInfos ??= BuildKeyToInfoLookup(diffContext, origOldStartIndex, oldEndIndexExcl, origNewStartIndex, newEndIndexExcl);
105+
102106
if (Equals(oldKey, newKey))
103107
{
104108
// Keys match
@@ -108,11 +112,6 @@ private static void AppendDiffEntriesForRange(
108112
else
109113
{
110114
// Keys don't match
111-
if (keyedItemInfos == null)
112-
{
113-
keyedItemInfos = BuildKeyToInfoLookup(diffContext, origOldStartIndex, oldEndIndexExcl, origNewStartIndex, newEndIndexExcl);
114-
}
115-
116115
var oldKeyItemInfo = oldKey != null ? keyedItemInfos[oldKey] : new KeyedItemInfo(-1, -1);
117116
var newKeyItemInfo = newKey != null ? keyedItemInfos[newKey] : new KeyedItemInfo(-1, -1);
118117
var oldKeyIsInNewTree = oldKeyItemInfo.NewIndex >= 0;

src/Components/Components/test/RenderTreeDiffBuilderTest.cs

+17
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,23 @@ public void RejectsClashingKeysInNewTree()
360360
Assert.Equal("More than one sibling has the same key value, 'key1'. Key values must be unique.", ex.Message);
361361
}
362362

363+
[Fact]
364+
public void RejectsClashingKeysEvenIfAllPairsMatch()
365+
{
366+
// This sort of scenario would happen if you accidentally used a constant value for @key
367+
368+
// Arrange
369+
AddWithKey(oldTree, "key1", "attrib1a");
370+
AddWithKey(oldTree, "key1", "attrib1b");
371+
372+
AddWithKey(newTree, "key1", "attrib1a");
373+
AddWithKey(newTree, "key1", "attrib1b");
374+
375+
// Act/Assert
376+
var ex = Assert.Throws<InvalidOperationException>(() => GetSingleUpdatedComponent());
377+
Assert.Equal("More than one sibling has the same key value, 'key1'. Key values must be unique.", ex.Message);
378+
}
379+
363380
[Fact]
364381
public void HandlesInsertionOfUnkeyedItemsAroundKey()
365382
{

0 commit comments

Comments
 (0)