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:
Why is the second Expander
not re-rendered and the parameter binding does not work either?
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.
- 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" />
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With