Search code examples
blazorblazor-server-sideblazor-client-side

Why does Blazor renders component twice


I have a simple Blazor component.

<div @onclick="HandleClick">Click me</div>

@code {

    public async Task HandleClick()
    {
        await Task.Run(()=> System.Threading.Thread.Sleep(1000));
    }

    protected override void OnAfterRender(bool firstRender)
    {
        Console.WriteLine("Rendered");
    }
}

When I click on the div "Rendered" is printed to console and after 1 sec again which means that blazor has rendered component twice. I understand that Blazor triggers an automatic re-render of a component as part of dispatching an event to it.

But why does it rerender after the task is completed? How can I avoid second render?

I have some JS interop in OnAfterRender lifecycle hook that now runs twice. I can add some sort of counter but that would polute my code and I would like to avoid that. I my HandleClick were a simple public void method then everything is ok but that is not always possible


Solution

  • You can use the firstRender variable like this:

    if(firstRender)
    {
       // Call JSInterop to initialize your js functions, etc.
       // This code will execute only once in the component life cycle.
       // The variable firstRender is true only after the first rendering of the 
       // component; that is, after the component has been created and initialized.
       // Now, when you click the div element firstRender is false, but still the 
       // component is rendered twice, before the awaited method (Task.Run) is called,
       // and after the awaited method completes. The first render occurs because UI 
       // event automatically invoke the StateHasChanged method. The second render 
       // occurs also automatically after an awaited method in an async method 
       // completes. This is how Blazor works, and it shouldn't bother you. 
    }