Search code examples
asp.net-coreblazorblazor-server-side

How can i see which code is setting my components parameter property


I've a general question concerning the parameters setting lifecycle for a Blazor component.

I've made a ordinary two way binding on my component. When I tested out this binding, it first seemed that nothing happens on changing the parameter value. But during debbung i noticed that indeed all binding steps are completed successfully. The bound parameter has a correct value on the parent component and the child component.

Now the strange thing comes in. I did not run the debugger to the end. I only stepped forward and saw that the property of the child component is set again with the original value. So I browsed my whole repository for the trigger of the setter. Now I decided to override the SetParameterAsync Method on my child component. Then I saw a frame which sets my property with the old value.

And now my question. Does anybody know a way to figure out which code or component sets the property. Do I have any object where I can watch the initiator of the parameter set operation?


Solution

  • on changing the parameter value

    You're not supposed to change your parameter value. A parameter property is an auto property. You don't change its value. Only the parent component is supposed to alter its value.

    Your child component should look like this:

    ChildComponent.razor

    <p><input type="text" @bind="BoundValue" @bind:event="oninput" /></p>
    
    <p>
        <button @onclick="ChangeValue">Change from Child</button>
    </p>
    
    
    
    @code {
        [Parameter]
        public string Property { get; set; }
    
        [Parameter]
        public EventCallback<string> PropertyChanged { get; set; }
    
        private string BoundValue
        {
            get => Property;
            set => PropertyChanged.InvokeAsync(value);
        }
    
        private Task ChangeValue()
        {
            return PropertyChanged.InvokeAsync($"New value set in Child {DateTime.Now}");
        }
    } 
    

    And your parent component may look like this:

    @page "/"
    
    
    <ChildComponent @bind-Property="MyProperty"/>
    
    <p>MyProperty: @MyProperty</p>
    
    @code 
    {
        private string MyProperty { get; set; } = "Value sent to the child.";
    } 
    

    Note that the parameter property named Property in the child component is never altered. This is how you should code.

    As you can understand by now, only the parent component should alter the parameter value, not the child. This explains why your property is assigned with the old value. To be more specific, when your parent component re-renders under a couple of conditions. The following is from the docs:

    A child component receives new parameter values that possibly overwrite existing values when the parent component rerenders. Accidentially 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:

    The child component is rendered with one or more parameter values from the parent component. The child writes directly to the value of a parameter. The parent component rerenders and overwrites the value of the child's parameter. More here

    Note: Debugging can't help you much is this respect... Note also that Blazor has specific algorithm that determines which types should be overwritten and under what conditions. Debugging won't help you much. It will only confuse you and lead you to believe that Blazor is buggish software. But what is going on here is by design...