In Blazor, the lifecycle refers to the various stages a component goes through. These stages allow developers to run specific code at key moments, such as when the component is created, updated, or removed. By understanding the component lifecycle, you can better manage resources, side effects, and performance. In this tutorial, we will cover:
A component goes through 5 stages:
StateHasChanged
is called.The stages will have the following order:
For proper component disposal, implementIDisposable
orIAsyncDisposable
, sinceDispose
andDisposeAsync
aren’t built into components by default.
You can run your code in each stage of the component lifecycle by overriding the corresponding method. Each stage has at least 1 method that can be overridden. In cases where a stage has 2 methods, 1 synchronous and 1 asynchronous, the synchronous method will execute first, followed by the asynchronous method. Check the execution order in this table:
Stage | Method | Executing order |
---|---|---|
SetParameters | SetParametersAsync |
1 |
Initialized | OnInitialized |
2 |
Initialized | OnInitializedAsync |
3 |
ParametersSet | OnParametersSet |
4 |
ParametersSet | OnParametersSetAsync |
5 |
AfterRender | OnAfterRender |
6 |
AfterRender | OnAfterRenderAsync |
7 |
Dispose | Dispose |
8 |
Dispose | DisposeAsync |
9 |
Here’s a video showing the lifecycle in action:
Dispose
method is invoked, signalling the component’s disposal.The Initialized stage occurs after the component’s parameters are set, marking the point where it’s fully constructed and ready for use. During this stage, you can perform tasks such as:
Releasing resources after use is critical to maintain performance and prevent unintended behaviours. While the garbage collector handles some resources automatically, others require explicit cleanup. Examples of resources needing manual release include:
To write your disposing code for a component, you need to implement IDisposable
in the component by using the @implements
directive and then declare a public void Dispose()
method. Here is an example:
@inject IJSRuntime JSRuntime @inject NavigationManager NavigationManager @implements IDisposable <div>Sample Text: @SampleText</div> @code { public string SampleText { get; set; } = ""; protected override void OnInitialized() { SampleText = "Blazor School"; NavigationManager.LocationChanged += OnLocationChanged; } public void OnLocationChanged(object? sender, LocationChangedEventArgs eventArgs) => JSRuntime.InvokeVoidAsync("alert", "Hello Navigator"); public void Dispose() => NavigationManager.LocationChanged -= OnLocationChanged; }
In the example, we have set the default value for SampleText
and subscribed to the NavigationManager.LocationChanged
event, and as good practice, we have unsubscribed from the NavigationManager.LocationChanged
event in the Dispose
method.
Some resources can only be disposed of asynchronously. To dispose of such resources, you need to implement IAsyncDisposable
:
@implements IAsyncDisposable ... @code { public async ValueTask DisposeAsync() { } }
The ParametersSet stage activates each time a component’s parameters are modified, whether from a URL update or a parent component adjustment, occurring after the Initialized stage. During this stage, you can override the OnParametersSet
or OnParametersSetAsync
methods to react to parameter changes—useful for tasks like refreshing displayed data or adjusting component state based on new inputs. This ensures the component stays in sync.
Consider this code sample:
@inject IJSRuntime JSRuntime <p>Component Parameter: @ComponentParameter</p> @code { [Parameter] public string ComponentParameter { get; set; } = ""; [Parameter] [SupplyParameterFromQuery] public string? UrlParameter { get; set; } = ""; protected override void OnParametersSet() { JSRuntime.InvokeVoidAsync("alert", "ParametersSet called in CHILD component."); } }
In this example, the component defines 2 parameters: ComponentParameter
, supplied by a parent component, and UrlParameter
, sourced from the URL query string via the [SupplyParameterFromQuery]
attribute. By overriding the OnParametersSet
or OnParametersSetAsync
method, you can respond to updates in either parameter.
The SetParameters stage is a combination of the OnInitialized stage and OnParametersSet stage. This means it is triggered when the component is initially constructed or when its parameters are updated, before the parameters are set. Also, the OnInitialized stage and OnParametersSet stage are both triggered by the SetParameters stage; as a result, you can completely skip those 2 stages. During this stage, you can override the SetParametersAsync
method to handle parameters early or create more stages.
We do not recommend you modify this stage due to many pitfalls in this stage unless you are building a component library and don’t want the developers who use your component to mandatory callbase.OnInitialized()
/base.OnParametersSet()
... and so on.
Consider the following example:
@inject IJSRuntime JSRuntime <h3>SetParametersStage</h3> @code { public async Task CustomLifecycleMethodAsync() { await JSRuntime.InvokeVoidAsync("alert", "This is a custom lifecycle method"); } protected override async Task OnInitializedAsync() { await JSRuntime.InvokeVoidAsync("alert", "OnInitializedAsync stage called"); } protected override void OnParametersSet() { JSRuntime.InvokeVoidAsync("alert", "OnParametersSet stage called"); } public override async Task SetParametersAsync(ParameterView parameters) { // To enable initialize and parameter set stages, uncomment the following line // await base.SetParametersAsync(parameters); // Because we skipped the base method, we need to manually set the parameters and update the UI parameters.SetParameterProperties(this); StateHasChanged(); await CustomLifecycleMethodAsync(); } }
In this example, overriding SetParametersAsync
introduces a custom stage through the CustomLifecycleMethodAsync
method, which displays an alert. By leaving the await base.SetParametersAsync(parameters)
call commented out, the Initialized and ParametersSet stages are skipped entirely. To compensate, the code manually applies the parameters using SetParameterProperties
and updates the UI with StateHasChanged
, ensuring the component reflects the new state before proceeding to the custom logic.
Once all preparations for rendering are complete (initialization finished and parameters assigned), Blazor initiates the rendering process, triggering the AfterRender stage. This stage is ideal for tasks such as:
These examples highlight just some of the possibilities for this stage; other tasks may also align well with its timing.
Here's an example to illustrate the AfterRender stage:
@inject IJSRuntime JSRuntime <button @onclick="StateHasChanged">Trigger AfterRender</button> @code { protected override async Task OnAfterRenderAsync(bool firstRender) => await JSRuntime.InvokeVoidAsync("alert", $"AfterRender stage triggered with firstRender is {firstRender}"); }
In the code, we demonstrate how bool firstRender
changes during the AfterRender stage. The following video will show how this example looks: