Understanding the lifecycle of Blazor components is crucial for building efficient and responsive web applications. This document outlines the key stages a Blazor component goes through from creation to disposal.
A visual representation of the Blazor Component Lifecycle:
Image source: Microsoft Docs
When a Blazor component is first created, an instance of its class is created. At this stage, parameters passed to the component are assigned.
The constructor of the component is executed during instantiation. Avoid performing complex operations or accessing parameters in the constructor, as parameters might not be fully initialized yet.
After instantiation, Blazor sets the component's parameters. This is followed by the execution of the SetParametersAsync
method if there are parameters to be set. Then, the OnInitialized
lifecycle event is invoked.
OnInitialized
This is the first opportunity to run C# code after the component has been instantiated and its parameters have been set. It's suitable for:
Example:
@code {
protected override void OnInitialized()
{
// Fetch initial data or set up state
Console.WriteLine("Component Initialized");
}
}
Once initialized, the component renders its UI. Blazor uses a diffing algorithm to compare the current render tree with the previous one and updates the DOM accordingly.
The OnParametersSet
and OnAfterRender
methods are related to rendering.
OnParametersSet
This method is called after OnInitialized
and every time the component receives new parameter values. It's a good place to perform logic that depends on parameter values that might change during the component's lifetime.
Example:
@code {
[Parameter]
public string Message { get; set; }
protected override void OnParametersSet()
{
// Logic that depends on the 'Message' parameter
Console.WriteLine($"Parameters set: {Message}");
}
}
OnAfterRender(bool firstRender)
This method is invoked after the component has finished rendering to the browser. The firstRender
parameter indicates whether this is the first render after initialization. Use this for:
Example:
@inject IJSRuntime JSRuntime
@code {
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
await JSRuntime.InvokeVoidAsync("console.log", "Component first rendered!");
}
Console.WriteLine("Component rendered.");
}
}
As the user interacts with the component or data changes, the component's state might be updated. When this happens, Blazor can trigger a re-render.
Forcing a re-render can be done using the StateHasChanged()
method. This method signals to Blazor that the component's state has changed and it needs to be re-rendered.
It's generally recommended to let Blazor manage re-renders automatically when parameters change or when event callbacks are invoked. Manually calling StateHasChanged()
should be done judiciously.
When a component is no longer needed (e.g., it's removed from the UI), Blazor disposes of it. The Dispose()
method is invoked to clean up any resources allocated by the component.
Dispose()
Implement this method to release unmanaged resources, unsubscribe from events, or cancel any ongoing asynchronous operations to prevent memory leaks.
Example:
@implements IDisposable
@code {
private Timer timer; // Example of a resource to dispose
protected override void OnInitialized()
{
timer = new Timer(1000);
timer.Elapsed += TimerElapsed;
timer.Start();
}
private void TimerElapsed(object sender, ElapsedEventArgs e)
{
// Do something every second
InvokeAsync(() =>
{
// Update state and potentially trigger UI updates
StateHasChanged();
});
}
public void Dispose()
{
Console.WriteLine("Component Disposing");
timer?.Stop();
timer?.Dispose();
// Unsubscribe from events or release other resources
}
}
Here's a quick overview:
Constructor()
: Component instantiation.SetParametersAsync(ParameterView parameters)
: Sets component parameters.OnInitialized()
: Component initialized for the first time.OnParametersSet()
: Parameters have been set or changed.OnAfterRender(bool firstRender)
: Component has finished rendering.StateHasChanged()
: Manually trigger a re-render (use with caution).Dispose()
: Component is being removed and its resources need to be cleaned up.By understanding and leveraging these lifecycle methods, you can build more robust, performant, and maintainable Blazor applications.