Reputation: 287
I'm creating a component Foo
that takes two parameters. I want to bind two variables like this:
<Foo SelectedPage="@SelectedPage" SelectedPageElement="@SelectedPageElement" />
How can I make sure I update both SelectedPage
and SelectedPageElement
at the same time and only have Foo
rerender after both variables are updated?
I want to be able to do something like
SelectedPage = nextPage;
SelectedPageElement = null
without rendering the component twice.
Upvotes: 0
Views: 587
Reputation: 396
You could make a
public record Selection(string SelectedPage, string SelectedPageElement)
and instead of two [Parameter]
make the [Parameter]
be an instance of the record.
Upvotes: 0
Reputation: 30016
There are various events that cause a re-render, Foo doesn't render just because you set SelectedPage = nextPage;
. It all depends on the context in which you are running those two lines of code.
The following code demonstrates a normal event driven example and shows the number of render events that occur.
<h3>Foo rendered @renders</h3>
@code {
[Parameter] public string? SelectedPage { get; set; }
[Parameter] public string? SelectedPageElement { get; set; }
// set to 1 as ShouldRender is not called on the first render event
private int renders = 1;
protected override bool ShouldRender()
{
renders++;
return true;
}
}
@page "/"
<h1>Hello</h1>
<Foo SelectedPage="@this.selectedPage" SelectedPageElement="@this.selectedPageElement" />
<div>
<button class="btn btn-primary" @onclick=this.OnClick>Update</button>
</div>
@code
{
private string? selectedPage;
private string? selectedPageElement;
private void OnClick()
{
selectedPage = "Hello";
selectedPageElement = "Me";
}
}
As you can see there's only one render event associated with the button click. You don't need to write extra code.
Upvotes: 2
Reputation: 2872
You can prevent unnecessary rerendering by overriding ComponentBase.ShouldRender()
.
An example, using simple data types for the component parameters:
ShouldRender()
, you can make sure that both of the parameters actually have an updated value before you allow rerendering to happen.The code for Foo may look something like:
[Parameter]
public int SelectedPage { get; set; }
[Parameter]
public int SelectedPageElement { get; set; }
private int _selectedPage;
private int _selectedPageElement;
protected override void OnInitialized()
{
_selectedPage = SelectedPage;
_selectedPageElement = SelectedPageElement;
}
protected override bool ShouldRender()
{
if (SelectedPage == _selectedPage)
{
return false;
}
if (SelectedPageElement == _selectedPageElement)
{
return false;
}
// Both parameters were updated --> update the tracking fields, let component rerender
_selectedPage = SelectedPage;
_selectedPageElement = SelectedPageElement;
return true;
}
Example fiddle illustrating the result here.
Upvotes: 0