-
Notifications
You must be signed in to change notification settings - Fork 10.4k
Description
Describe the bug
Let's say we have a list of items. When clicking on a item we want to display a content for that item. We setup an unordered list and when adding an item to list we create a div element that holds an item content but it's visibility is hidden until a user click on a list item. Clicking on another list item causes a current div to hide itself (not remove from DOM but set display attribute to none) and a new div corresponding to a list item to become visible.
When adding new list items and clicking on them a binary message size increases. I've read through the documentation and watched Blazor in more depth talk and I can't figure out why?
Looking at developer tools only thing that changes is display attribute on only two divs, no matter the current list items count.
If the diffing algorithm works as advertised I would expect the binary message received from server to have a constant size because only two attributes change or am I missing something
EDIT:
If you comment out a second foreach loop and click on the li item binary message size increases when adding more items to the list.
What is going on? I understand that a click event triggers a render but there are no changes on the DOM and the diffing algorithm shouldn't find any differences between current and new DOM state.
To Reproduce
Here is a simple code to reproduce the behaviour
<button @onclick="AddTenMore">Add ten items</button>
<br/>
<br/>
<div style="width:400px; float:left">
<ul>
@foreach (var item in Items)
{
<li @onclick="@(()=>SetActiveItem(item))">@item.Id</li>
}
</ul>
</div>
<div style="width:400px; margin-left:250px">
@foreach(var item in Items)
{
<div @key="item.Id" style="display:@GetVisibility(item)">
<div>This is content for item <b>@item.Id</b></div>
</div>
}
</div>
<br/>
@code {
public List<ListItem> Items { get; set; } = new List<ListItem>();
private ListItem ActiveItem { get; set; }
public void AddTenMore()
{
for(var i = 0; i < 10; i++)
{
Items.Add(new ListItem()
{
Id = Guid.NewGuid().ToString()
});
}
}
public string GetVisibility(ListItem item)
{
if (ActiveItem == null)
return "none";
return item == ActiveItem ? "block" : "none";
}
public void SetActiveItem(ListItem item)
{
ActiveItem = item;
}
public class ListItem
{
public string Id { get; set; }
}
}
Further technical details
- ASP.NET Core 3.1 in VS