我正在创建一个组件Foo
,它需要两个参数。我想这样绑定两个变量:
<Foo SelectedPage="@SelectedPage" SelectedPageElement="@SelectedPageElement" />
我如何确保我同时更新SelectedPage
和SelectedPageElement
,并且在两个变量更新后只有Foo
呈现?
我希望能够做一些像
SelectedPage = nextPage;
SelectedPageElement = null
而不渲染组件两次。
有各种各样的事件会导致重新渲染,Foo不会仅仅因为你设置了SelectedPage = nextPage;
而渲染。这完全取决于您运行这两行代码的上下文。
下面的代码演示了一个普通的事件驱动示例,并显示了发生的呈现事件的数量。
Foo
<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";
}
}
正如你所看到的,只有一个渲染事件与按钮点击相关。你不需要写额外的代码。
您可以通过重写ComponentBase.ShouldRender()
来防止不必要的重新渲染。
一个使用简单数据类型作为组件参数的例子:
- 您可以为每个参数创建一个私有字段。私有字段在组件初始化时填充,然后用于跟踪最新更新的值集(即两个参数更新的最新状态)。然后,通过重写
ShouldRender()
,你可以确保这两个参数实际上有一个更新的值之前,你允许重新渲染发生。
Foo的代码可能看起来像:
[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;
}
示例显示了这里的结果。
你可以做一个
public record Selection(string SelectedPage, string SelectedPageElement)
,而不是两个[Parameter]
,使[Parameter]
成为记录的实例。