Blazor

Blazor Bites - Component Lifecycle Methods

Blazor Bites Series


Post valid for: Blazor 0.6.0
Please remember that Blazor is an experimental project and is going to be changing regularly. IT IS NOT PRODUCTION READY.


Component Lifecycle Methods

When you create a component in Blazor it must derive from BlazorComponent. There are two reasons for this. One is that BlazorComponent implements IComponent and Blazor uses this interface to locate components throughout your project. It doesn't rely on a folder convention. Second is that BlazorComponent contains important lifecycle methods.

In this post I'm going to cover the lifecycle methods available in the current version of Blazor. I'm also going to cover a couple of other methods which aren't life cycle but are used in the life cycle process.

OnInit() & OnInitAsync()

These methods are called once the component is ready to start. This happens after the component has received its initial parameters from its parent in the render tree.

OnInit is called first, then OnInitAsync. Any asynchronous operations, which require the component to re-render once they complete, should be placed in the OnInitAsync method.

Example
<!-- OnInit -->

@page "/oninit-example"

<h1>@title</h1>

<p>I was rendered at @timeRendered</p>

@functions {

    private string title { get; set; }
    private string timeRendered { get; set; }

    protected override void OnInit()
    {
        title = "Hello World";
        timeRendered = DateTime.Now.ToShortTimeString();
    }

}
Example
<!-- OnInitAsync -->

@page "/oninitasync-example"
@inject IBudgetService BudgetService 

<h1>View Expenses Async</h1>

@if (Expenses == null)
{
    <p>Loading...</p>  
}
else
{
    <table>
        @foreach (var expense in expenses) 
        {
            <tr>
                <td>
                    @expense.Description
                </td>
                <td>
                    @expense.Amount
                </td>
            </tr>
        }
    </table>
}

@functions {

    private Expense[] expenses;

    protected override async Task OnInitAsync()
    {
        expense = await BudgetService.GetExpensesAsync();
    }

}

OnParametersSet() & OnParametersSetAsync()

The OnParametersSet and OnParametersSetAsync methods are called when a component is first initialised.

After initialisation, OnParametersSet and OnParametersSetAsync are called each time new or updated parameters are receieved from the parent in the render tree.

Example
<!-- Parent Component -->

@page "/increment"

<h1>Increment Counter</h1>

<DisplayValue Counter=@CounterValue />

<button onclick="@IncrementCounter">Increment</button>

@functions {

    int CounterValue = 0;

    void IncrementCounter()
    {
        CounterValue = CounterValue += 2;
    }

}
<!-- Child Component -->

@page "/displayvalue"

@counterOutput

@functions {

    [Parameter]
    private int counter { get; set; }

    private string counterOutput;

    protected override void OnParametersSet()
    {
        counterOutput = counter.ToString() + " and counting...";
    }
    
}

OnAfterRender && OnAfterRenderAsync

The OnAfterRender and OnAfterRenderAsync methods are called after each render of the component. At the point they are called you can expect that all element and component references are populated.

This means that if you need to perform an action, such as attaching an event listener, which requires the elements of the component to be rendered in the DOM. Then these methods are where you can do it. Another great use for these lifecycle methods are for JavaScript library initialisation, which require DOM elements to be in place to work.

Misc

As I mentioned I'd be covering a couple of methods that aren't lifecycle methods but are used in the lifecycle process. These methods are the ShouldRender and StateHasChanged.

ShouldRender()

This method returns a boolean to indicate if a components UI can be re-rendered. However, it is only called after the initial render of a component. This is mentioned by Steve Sanderson in this GitHub issue.

StateHasChanged()

This method notifies the component that its state has changed. It is called after any lifecycle method has been called. It can also be invoked manually to trigger a UI re-render.

This method looks at value returned from ShouldRender to decide if a UI re-render should happen. However, this only happens after the component has been rendered for the first time.