In this lesson, you will learn how to use the @key attribute to ensure Blazor updates dynamic lists efficiently by helping the rendering engine track specific items during changes.
The Challenge of List Reordering
When you render a list of items in Blazor, the framework compares the new list to the old one to determine what changed. By default, Blazor compares these items by their position in the list. If you add an item to the top of the list or remove one from the middle, Blazor often re-renders every subsequent element because their relative indices have changed. This is inefficient, especially when those components hold their own state.
Using @key for Identity
The @key attribute acts as a unique identifier for an element or component within a loop. When you provide a key, Blazor stops relying on index position and instead tracks items based on that unique value. If the order of your list changes, Blazor simply moves the existing DOM elements to their new positions rather than destroying and recreating them.
Consider a dynamic list of user tasks:
@foreach (var task in Tasks)
{
<div @key="task.Id">
<TaskComponent TaskData="task" />
</div>
}
In this example, task.Id serves as the unique identifier. If you prepend a new task to the collection, Blazor recognizes that all previous tasks still exist and have the same Id. It will only render the new item, leaving the existing TaskComponent instances untouched.
When to Use It
You should prioritize using @key whenever:
- Your list is dynamic (items are added, removed, or reordered).
- The items in the list hold internal state (like a form field where the user is typing).
- The list items are complex components that are expensive to re-render.
By providing this hint to the RenderTree, you reduce unnecessary DOM operations and prevent bugs where UI state becomes misaligned with the underlying data after a list operation.
Key Takeaway: Always use the @key attribute with a unique identifier when rendering dynamic lists to ensure Blazor performs minimal, targeted DOM updates rather than re-rendering the entire collection.