If there is a Blazor component and it has three parameters, is it possible to only trigger logic within OnParametersSet method when a specific one of the three parameters is changed? Is there a way to check which parameters were changed while inside OnParametersSet?
Blazor: Is it possible to trigger OnParametersSet method for a specific parameter?
173 Views Asked by d1du AtThere are 4 best solutions below
On
You can do something like this in SetParametersAsync
[Parameter] public int MessageId { get; set; }
[Parameter] public string? Text { get; set; }
private int _messageId;
private bool _notFirstRender;
public override Task SetParametersAsync(ParameterView parameters)
{
// You must consume parameters immediately
parameters.SetParameterProperties(this);
// short circuit if we've already rendered once and the messageid is the same
if (this.MessageId == _messageId && _notFirstRender)
return Task.CompletedTask;
_messageId = this.MessageId;
_notFirstRender = true;
// Run the lifecycle events
// Note passing on an empty ParameterView to the base. We've already set them
return base.SetParametersAsync(ParameterView.Empty);
}
For a more general approach see this MS document - https://learn.microsoft.com/en-us/aspnet/core/blazor/performance?view=aspnetcore-8.0#implement-setparametersasync-manually
On
is it possible to only trigger logic within OnParametersSet method when a specific one of the three parameters is changed?
OnParametersSet is part of lifecycle events,I don't think it would be triggered without triggering other lifecycle events
Is there a way to check which parameters were changed while inside OnParametersSet?
You could check which parameter has changed within SetParametersAsync method:
public override async Task SetParametersAsync(ParameterView parameters)
{
foreach (var parameter in parameters)
{
var currentVal = this.GetType().GetProperty(parameter.Name)?.GetValue(this, null);
var newVal = parameter.Value;
// In some cases,you could set the properties one by one
manually as mentioned in the document
this.GetType().GetProperty(parameter.Name).SetValue(this, newVal);
}
await base.SetParametersAsync(ParameterView.Empty);
}
A whole example:
Child component:
<h1>@Title</h1>
<p role="status">Current count: @Count</p>
@code {
[Parameter]
public int Count{ get; set; }
[Parameter]
public string? Title { get; set; }
public override async Task SetParametersAsync(ParameterView parameters)
{
foreach (var parameter in parameters)
{
var currentVal = this.GetType().GetProperty(parameter.Name)?.GetValue(this, null);
var newVal = parameter.Value;
this.GetType().GetProperty(parameter.Name).SetValue(this, newVal);
}
await base.SetParametersAsync(ParameterView.Empty);
}
}
parent component:
<ChildComponent Count="@currentCount" Title="@title"></ChildComponent>
<button class="btn btn-primary" @onclick="IncrementCount">Count</button>
<button class="btn btn-primary" @onclick="Title">NewTitle</button>
@code {
private int currentCount = 0;
private string title = "MyTitle";
private void IncrementCount()
{
currentCount++;
}
private void Title()
{
title = "NewTitle";
}
}
Once I click Count button:
Once I click Title button:
On
- Using a prev field with the OnParametersSet() method
@page "/showcount1"
<span>@Count</span> <span>@Postfix</span>
@code {
[Parameter] public int Count { get; set; }
int prevCount;
[Parameter] public string Postfix { get; set; } = "time(s)";
protected override void OnParametersSet()
{
if (prevCount != Count)
{
prevCount = Count;
AdditionalAction();
}
}
void AdditionalAction() { }
}
- Overriding the SetParametersAsync() method
@page "/showcount2"
<span>@Count</span> <span>@Postfix</span>
@code {
[Parameter] public int Count { get; set; }
[Parameter] public string Postfix { get; set; } = "time(s)";
public override async Task SetParametersAsync(ParameterView parameters)
{
// Get the value before it changes. This must be done before calling base.SetParametersAsync
var countChanged = parameters.GetValueOrDefault<int>(nameof(Count)) != Count;
await base.SetParametersAsync(parameters); // Use the default implementation to set parameters
if (countChanged)
{
AdditionalAction();
}
}
void AdditionalAction() { }
}


You could try use c# properties {get;set;} to trigger an action when parameter is set. Try following: Child.razor
Home.razor
Test
