Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding Overwritten Parameters problem in Blazor

Tags:

c#

.net

blazor

I'm learning Blazor by reading through Microsoft's Blazor documentation and have problem understanding this example on Overwritten Parameters problem. Here is the example code:

Child component:

<div @onclick="Toggle" class="card bg-light mb-3" style="width:30rem">
    <div class="card-body">
        <h2 class="card-title">Toggle (<code>Expanded</code> = @Expanded)</h2>

        @if (Expanded)
        {
            <p class="card-text">@ChildContent</p>
        }
    </div>
</div>

@code {
    [Parameter]
    public bool Expanded { get; set; }

    [Parameter]
    public RenderFragment ChildContent { get; set; }

    private void Toggle()
    {
        Expanded = !Expanded;
    }
}

Parent:

@page "/expander-example"

<Expander Expanded="true">
    Expander 1 content
</Expander>

<Expander Expanded="true" />

<button @onclick="StateHasChanged">
    Call StateHasChanged
</button>

What's confusing me is:

  1. Why is the second Expander not re-rendered and the parameter binding does not work either?

  2. What exactly is the problem the documentation tries to show here? When a parent component reset its state, I would expect the change to be reflected on the child components, which is exactly what the first supposedly problematic expander does.

like image 876
DaPanda Avatar asked Sep 20 '25 21:09

DaPanda


1 Answers

  1. Why is the second Expander not re-rendered and the parameter binding does not work either?

Because there is one parameter of a simple value type and a reference type (ChildContent) that is null. The render engine decides "nothing has changed here" and skips it.

That that boolean parameter was changed 'from the inside' is precisely the problem of 'overwritten parameters'.

The first <Expander> has a non-null ChildContent and then the engine does not look any deeper, it assumes that that is a mutable object and rerenders the component.

Note that that means there is a hidden cost in passing complex objects instead of valuetypes. <PersonCard PersonId="person.Id" /> will not be re-rendered as often as <PersonCard Person="person" />

like image 62
Henk Holterman Avatar answered Sep 22 '25 10:09

Henk Holterman