The Life Cycle Of a Razor Component

The ComponentBase type, which every Razor Component derives from, provides a number of virtual methods that you can override to hook into various points during the life cycle of a Razor component. These points are (in the order in which they happen)

  1. Whenever parameter values are set
  2. When the component is initialised
  3. Each time the component has been rendered

When Parameter Values Are Set

The first hook in the component life cycle is available when a component's parameters receive their values from the component's parent. The virtual methods that you can override at this point are OnParametersSet and its async counterpart, OnParametersSetAsync. These methods are called when the component is initialised and whenever parameters are subsequently updated in the parent.

In the following example, the Counter component has been modified so that the incremented count of clicks is provides as a parameter value:

@page "/counter"

<h1>Counter</h1>

<p>@message</p>

@code {
    [Parameter]
    public int count { get; set; } = 0;
    string message { get; set; }

    protected override void OnParametersSet()
    {
        if (string.IsNullOrEmpty(message)){
            message = "Parameters set for the first time";
        }
        else
        {
            message = "Parameter reset to " + count;
        }
        base.OnParametersSet();
    }
}

The Index component is altered to increment a value and pass that to the count parameter of the Counter:

@page "/"

<h1>Hello, world!</h1>

Welcome to your new app.

<Counter count=theCount />

<button @onclick=incrementCount>Click</button>

@code{
    int theCount { get; set; } = 1;
    void incrementCount()
    {
        theCount++;
    }
}

When you first run this example, the message says "Parameters set for the first time". When the button is clicked, the parameter value is incremented and the message is updated to "Parameter reset to 2", demonstrating that the method is called after parameter values are set.

The OnParametersSetAsync method is intended for use where the logic that you want to apply requires async operations, such as calls to web services etc.

Setting Parameter Values

If you need to execute some code before the parameter values are set, you can override the SetParametersAsync method, which takes a ParameterView object as an argument representing the collection of parameters supplied to the component.

The ParameterView object exposed a TryGetValue method for accessing parameters by name:

[Parameter]
public int MyParam { get; set; }

public override async Task SetParametersAsync(ParameterView parameters) 
{
  if (parameters.TryGetValue(nameof(MyParam), out int i))
  {
    ...
  }
  await base.SetParametersAsync(parameters); 
}

When The Component Is Initialised

The component is initialised after it has received parameters from its parent. At that point, the OnInitialized and OnInitializedAsync methods are called. Override one of these methods to perform additional initialisation after the component has been created. This is the point where you will usually make calls to Web API services to obtain data for the component, for example. This snippet is from the FetchData component where the data is required for the component before it can be rendered:

protected override async Task OnInitializedAsync()
{
    forecasts = await Http.GetFromJsonAsync<WeatherForecast[]>("WeatherForecast");
}

And this example is from the Tour Of Heroes tutorial, where the data that is also required for rendering the component relies on a parameter value having been set:

Hero hero { get; set; }
[Parameter]
public int Id { get; set; }

protected override async Task OnInitializedAsync()
{
    hero = await heroService.GetHero(Id);
}

After The Component Has Rendered

The OnAfterRender and OnAfterRenderAsync methods are called after the component has been rendered for the first time and subsequently re-rendered as a result of state changes and the browser's DOM has been updated accordingly. At this point, element and component references are available so this hook is ideal for performing initialisation of JavaScript resources that depend on DOM elements.

Both methods take a bool named firstRender as an argument. This is set by the framework and is true when the component is rendered for the first time. You can use this flag to prevent one-time initialisation being executed unnecessarily when the component is re-rendered.

@inject IJSRuntime JS
JSObjectReference module;
protected override void OnAfterRender(bool firstRender) 
{ 
    if(firstRender)
    {
        module = await JS.InvokeAsync<JSObjectReference>("import", "./js/exampleJsInterop.js");
    }
}

Use OnAfterRenderAsync to call asynchronous methods, for example, JavaScript methods that return promises or observables.


protected override Task OnAfterRenderAsync(bool firstRender) 
{ 
    //...
}

Prevent Rendering

The ShouldRender method returns a bool that determines whether a component should be re-rendered. The component will still render at least once. You can use this method to suppress UI refreshing. In the following example, the Counter component has been modified so that ShouldRender returns true when the currentCount value is an even number:

@page "/counter"

<h1>Counter</h1>

<p>Current count: @currentCount</p>

<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>

@code {
    private int currentCount = 0;
    private bool shouldRender;
    protected override bool ShouldRender() => shouldRender;
    private void IncrementCount()
    {
        currentCount++;
        shouldRender = currentCount % 2 == 0;
    }
}

Each click of the button results in the currentCount value incrementing by 1, but the UI only refreshes on every other click.

Last updated: 15/02/2023 08:59:45

Latest Updates

© 2023 - 2024 - Mike Brind.
All rights reserved.
Contact me at Outlook.com