Search code examples
blazorblazor-client-side

Blazor: execution of irrelevant code block upon ui update


In the sample code bellow, I add a Counter component to counters just once when the page is first gets initialized and using onclick event of "get count" button, I get the Count of counters;

@page "/"

<button @onclick="@(() => count = counters.Count)">get count</button>

<p>Count: @count</p>

@for (int i = 0; i < 1; i++)
{
    counters.Add(new Counter());
}

@code {
    private int count;
    private List<Counter> counters;

    protected override void OnInitialized()
    {
        counters = new List<Counter>();
    }
}

But why every time I press "get count" button, the count variable increases by one? (as if the @for block also gets executed)

Blazor WebAssembly 3.2.0


Solution

  • Of course the @for block also gets executed. Otherwise how could you get the count variable increase by one, as a new Counter object is added to the list.

    You should realize a fundamental aspect of Blazor: A UI event, such as click event, results in re-rendering of the component; thus all the view portion of the component is re-render. Perhaps you thought that only the lambda expression is executed ? In matter of fact, all the view is re-render. Again this is a fundamental principal of Blazor, which you should understand well, and take it into account when you design your components.

    Any how, you shouldn't instantiate components like that. Components are classes that considered a special case because they should only be instantiated as elements, as for instance <Counter/>. The reason for this anomality is that components are objects that rendered as Html DOM elements, and need a special handling of the system when created. When you create a component with the new key word, this handling does not take place, and no renderer object is involved.

    However, you may create a collection of component references to components, like this:

    <Counter @ref="counter1" />
    
    @code
    {
       private Counter counter1;
    }
    

    Hope this helps...