Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

318
Vistas
Understanding Overwritten Parameters problem in 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.

over 4 years ago · Santiago Trujillo
3 Respuestas
Responde la pregunta

0

  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" />

over 4 years ago · Santiago Trujillo Denunciar

0

The issue is described in this paragraph.

A child component receives new parameter values that possibly overwrite existing values when the parent component rerenders. Accidentally overwriting parameter values in a child component often occurs when developing the component with one or more data-bound parameters and the developer writes directly to a parameter in the child

If you don't want child component to depend on parent property, don't pass this property as a parameter to the child. To make example explicit, they trigger StateHasChanged method to initiate change detection on the parent page. This, in turn, triggers rerendering of the child, which may not be a desired behavior if you want to keep child expander open. This is why they recommend to use private variable inside child to isolate its state from the parent.

This is NOT the biggest issue though :)

What MSDN doesn't tell you is that working with Blazor, sooner or later you will realize that it's change detection policy is significantly different compared to widely used SPA frameworks, like Angular or React. These frameworks detect only changes of the internal state (class variables) defined in the component. On the contrary, Blazor likes to re-render entire page and all its children even in some arbitrary cases, e.g. when you clicked at some random place on the page.

How do I stop blazor @onclick re-rendering page

In other words, you may see the same issue even if you don't call StateHasChanged explicitly.

over 4 years ago · Santiago Trujillo Denunciar

0

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.

The objective is to warn against using public parameters to maintain the internal state of a component that you want to control only from the inside of the component.

Visualize a scenario where you have an editable Title and its details in the collapsed state. The model class Title also has some other properties (Skipping for brevity).

Consider the following:

<TitleEditor Title="@title" @OnTitleChanged="RefreshTitle"/>

<Details Content="@content" CollapseState="@areDetailsCollapsed"/>
    

@code
{
   TitleClass title = new ();
   ContentClass content = new ();
   bool areDetailsCollapsed = true;

   void RefreshTitle(string title)
   {
     title.Text = title;
     StateHasChanged();
   }
}

The user updates the title. This calls "RefreshTitle" which is intended to update only the Title. However, since the reference type parameters are involved, Details gets refreshed too. That will result in the internal collapse state of Details will be reset. Which is a wholly unintended side effect.

Further, StateHasChanged() cascade refreshes on every child component down the tree. Thus any StateHasChanged() anywhere in any parent node will cause a component to losing its state.

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda