ASP.NET Core Blazor components lifecycle

  • Gérald Barré

ASP.NET Core Blazor components lifecycle allows the user to perform additional operations on components during component initialization and rendering. It's also useful to release resources when the component is removed from the page.

Here's the Blazor components lifecycle:

#SetParametersAsync

This method sets the value of the properties decorated by [Parameter] or [CascadingParameter] by using the values provided by the parent component or by cascaded parameters. This is a good place to set default parameter values or read values from the query string.

public override async Task SetParametersAsync(ParameterView parameters)
{
    await base.SetParametersAsync(parameters);
}

#OnInitialized / OnInitializedAsync

Allow to initialize data after the parameter properties are set. This method is called once per component in Blazor WebAssembly. In Blazor Server it could be called twice when using pre-rendered mode. You can use these methods to execute a code only once in your code. For instance, you can get the set up the link between 2 components as in the Grid component.

protected override void OnInitialized()
{
}

protected override Task OnInitializedAsync()
{
}

#OnParametersSet / OnParametersSetAsync

OnParametersSetAsync and OnParametersSet are called after OnInitialized or when the parameters are changed. You can use these methods to compute things based on the parameter. For instance, you can compute any property/field that based its value on the parameters.

protected override void OnParametersSet()
{
}

protected override Task OnParametersSetAsync()
{
}

#OnAfterRender / OnAfterRenderAsync

OnAfterRenderAsync and OnAfterRender are called after a component has finished rendering. Element and component references are populated at this point. You can use this step to call JavaScript code on the elements. For instance, in the Blazor Modal component, I use this method to open the modal using JavaScript.

protected override void OnAfterRender(bool firstRender)
{
}

protected override Task OnAfterRenderAsync(bool firstRender)
{
}

#ShouldRender

You can use this method if you want to control whether a component needs to re-render after its state changed. This method is called after an explicit call to StateHasChanged or after an event is handled. You can use this method to prevent Blazor from refreshing the UI after a user has interacted with the component if you know it is not needed. As shown in the next section, StateHasChanged can be called twice per event handler. If you have a complex rendering logic, overriding ShouldRender could be a good way to optimize the component.

protected override bool ShouldRender()
{
    return base.ShouldRender();
}

#Event handlers

Event handlers can be synchronous or asynchronous in Blazor. In the case of a synchronous event handler StateHasChanged is called after the event handler. In the case of an asynchronous method, StateHasChanged is called twice: once when the synchronous part of the method ends, and a second time when the task is completed.

<button @onclick="OnClick">Synchronous</button>
<button @onclick="OnClickAsync">Asynchronous</button>

@code{
    void OnClick()
    {
    } // StateHasChanged is called by the base class (ComponentBase) after the method is executed

    async Task OnClickAsync()
    {
        text = "click1";
        // StateHasChanged is called by the base class (ComponentBase) here as the synchronous part of the async method ends
        await Task.Delay(1000);
        await Task.Delay(2000);
        text = "click2";
    } // StateHasChanged is called by the base class (ComponentBase) after the returned task is completed
}

If you want to prevent a user from clicking twice on a button, you can check the following post: Preventing double form submission in a Blazor app

#Component disposal with IDisposable

If a component implements IDisposable, the Dispose method is called when the component is removed from the UI. You can use this method to unsubscribe from events you may have subscribe previously, dispose a timer, cancel an asynchronous operation, etc. You can use @implements IDisposable to indicate your component implement the interface:

@implements System.IDisposable

<div>A component that implements IDisposable</div>

@code {
    public void Dispose()
    {
    }
}

IAsyncDisposable is not supported for components. However, this should be supported in the next version of Blazor thanks to the following pull request.

Do you have a question or a suggestion about this post? Contact me!

Follow me:
Enjoy this blog?Buy Me A Coffee