Blazor is setting component parameter every time I interact with component

2k Views Asked by At

What I want to achieve is to call a function every time Parameter value of a component is updated, So I created a component with a Parameter and call a method inside its setter like this.

private LookupConfig _lookupConfig;

Parameter]
public LookupConfig Config { get { return _lookupConfig; } set { _lookupConfig = value; Console.WriteLine("Parameter Setter"); InitializeDropdownValues(); } }

In my parent component, I have a property.

public LookupConfig CustomerDropdown = new LookupConfig { LookupType = LookupType.Customer };

and I am passing it to child component like this.

<NeeleezAutoComplete Config="CustomerDropdown"/>

but every time I interact with NeeleezAutoComplete component setter of Parameter property Config is get called.

is it intentional behaviour of blazor parameters am i missing something ? and how do i achieve this functionlaity?

2

There are 2 best solutions below

2
On BEST ANSWER

is it intentional behaviour of blazor parameters

Yes, this is by design. Blazor tracks parameter changes very lightly.

The solution seems simple:

set 
{ 
  if (_lookupConfig == value) return;   // no change? Out of here. 
  _lookupConfig = value; 
  Console.WriteLine("Parameter Setter"); 
  InitializeDropdownValues(); 
}

You may want to check Equality for LookupConfig but normally the defaults should suffice.

2
On

I think this code is fairly self explanatory.

<h3>MyDiv</h3>

@code {
    private bool veryBad;
    private bool bad;
    private bool good;

    [Parameter] public bool VeryBad
    {
        get => this.veryBad;
        set
        {
            this.veryBad = value;
            // Do lots of stuff
        }
    }

    [Parameter] public bool Bad
    {
        get => this.bad;
        set
        {
            this.bad = value;
            // Do something trivial
        }
    }

    [Parameter] public bool Good { get; set; }

    public override async Task SetParametersAsync(ParameterView parameters)
    {
        parameters.SetParameterProperties(this);

        if (!this.good.Equals(this.Good))
        {
            // Do something 
        }
        await base.SetParametersAsync(ParameterView.Empty);
    }
}

The point is that any [Parameter] should look (exactly) like this:

[Parameter] public bool Good { get; set; }

If you want to do some checking, trigger some code if a specific value changes,.... do it in SetParametersAsync if you need to use it immediately, or in OnParametersSet{async} if you don't.

Set the parameters by calling parameters.SetParameterProperties(this); in the first line releases the Renderer to carry on it's job (when it gets thread time). Note we call the base method with an empty ParameterView because we've already set them.

Adding code into setters means the setting code get run as part of parameters.SetParameterProperties, potentially slowing the whole Renderer process.