I have multiple instances of a component on a page with each component binding to a different variable:
Index.razor:
<Select Value="@ValueOne">
</Select>
<Select Value="@ValueTwo">
</Select>
<button @onclick="ClickMe">click me</button>
Index.razor.cs:
public partial class Index
{
private string ValueOne { get; set; } = "1";
private string ValueTwo { get; set; } = "2";
private void ClickMe()
{
ValueOne = "3";
}
}
In the select component I react to the change of the binded Value parameter as follows:
public partial class Select
{
[Parameter]
public string Value { get; set; } = default!;
protected override void OnParametersSet()
{
System.Console.WriteLine("Parameter Set");
}
}
Now when I press the button in Index.razor, it only updates a single variables binded to one of the components, but at run time, the OnParametersSet method is called for every instance of the component even though only one needs updating.
This is concerning as in my actual app I will be displaying over 50 of these on a page (one for each row in a table) therefore it will result in a large number of calls to OnParametersSet.
Is this the expected behaviour in Blazor or have I gone about this the wrong way?
Here's a slightly refactored version of your code to show set and render times within the components.
It works exactly as it should. The first component has set called and renders whenever you click the button. Nothing happens on the second component.
Therefore, there must be code you aren't showing us? Another object type
Parameter?MySelect.razor
Index.razor
The MayHaveChanged Code
For the record, the code used by the Renderer to evaluate state on the parameter list, and dictate if it calls
SetParametersAsync(which then callsOnParametersSet{Async}) is this:So unless a parameter is null AND hasn't changed, OR is a
IsKnownImmutableTypeand hasn't changed thenSetParametersAsyncgets called just in case. And it's a tripwire: it only takes one parameter to trip the fuse!