If you have only a few items, you should be able to use if/else flow to tell the render tree to show or remove the components. If you have a list of items, simply remove the item from the list and have the component re-render itself. Here is an example of a to-do list which dynamically adds/removes a div.
<input @bind-value="newItem"/><button @onclick="addItem" >Add Item</button>
@foreach(var item in ToDoList)
{
<div>@item <button @onclick="(()=>removeItem(item))">Remove</button></div>
}
@code {
string newItem = "";
List<string> ToDoList = new List<string>() { "Get Eggs", "Get Milk", "Get Coffee", "Get More Coffee" };
private void removeItem(string item)
{
ToDoList.Remove(item);
}
private void addItem()
{
ToDoList.Add(newItem);
newItem = "";
}
}
Of course you can replace the "div" with any blazor component and it will work exactly the same. The rendertree is built to efficiently handle scenarios like re-rendering after a list has been changed.
In the real-world, it might be more realistic to track changes using a property instead of simply adding and removing items from a list. In this way we can package up a list of our changes and send them to a server somewhere which will issue (add, update,delete) commands as needed. See my quick and dirty demo below:
Note that I've added a simple class SimpleString with a ToDo property appended. I've changed the foreach loop to check the property and build the To-Do and Completed sections accordingly.
<input @bind-value="newItem"/><button @onclick="addItem" >Add Item</button>
<h3>To-Do</h3>
@foreach(var item in ToDoList.Where(x=>x.ToDo))
{
<div>@item.Value <button @onclick="(()=>removeItem(item))">Remove</button></div>
}
<h2>Completed</h2>
@foreach(var item in ToDoList.Where(x=>!x.ToDo))
{
<p>@item.Value</p>
}
@code {
class SimpleString
{
public string Value { get; set; }
public bool ToDo { get; set; }
}
string newItem = "";
bool showComponent = true;
List<SimpleString> ToDoList = new List<SimpleString>() { new SimpleString { Value = "Get Eggs", ToDo = true }, new SimpleString { Value = "Get Milk", ToDo = true }, new SimpleString { Value = "Get Coffee", ToDo = true }, new SimpleString { Value = "Get More Coffee", ToDo = true } };
private void removeItem(SimpleString item)
{
item.ToDo = false;
}
private void addItem()
{
ToDoList.Add(new SimpleString { Value = newItem, ToDo = true });
newItem = "";
}
}
It's also worth noting that Blazor components can implement the IDisposable interface in case you need to tap into the "disposal" of a component to free up unmanaged resources. In Blazor, an IDisposable component fires its dispose when the component is removed from the UI. In my example, it is not necessary to use IDisposable, but the dispose method would be called after the removeItem method completed via button click.