【发布时间】:2020-10-29 00:00:04
【问题描述】:
这个问题已经被问过here,但重新提交了一个更清晰的例子(希望如此)。
在尝试确定 Blazor 何时以及如何重新渲染和更新状态时,我注意到了这种奇怪的行为。
取以下简单组件Test1Component:
@if (_show) {
<h3>Test1Component</h3>
}
@code {
private bool _show = true;
public void Show() {
_show = true;
}
public void Hide() {
_show = false;
}
}
在另一个组件中使用时,调用 Show 或 Hide 不会做任何事情:
<Test1Component @ref="_test1Component"></Test1Component>
<button type="button" @onclick="(() => { if (_test1Component != null) _test1Component.Hide(); })">Hide Test</button>
<button type="button" @onclick="(() => { if (_test1Component != null) _test1Component.Show(); })">Show Test</button>
@code{
Test1Component _test1Component;
}
为了让它工作,您必须将StateHasChanged() 添加到Show 和Hide 方法中。但是,如果我们将实现更改为包含 RenderFragment,Show 和 Hide 方法就会神秘地开始工作。
@if (_show) {
<h3>@ChildContent</h3>
}
@code {
private bool _show = true;
[Parameter] public RenderFragment ChildContent { get; set; }
public void Show() {
_show = true;
}
public void Hide() {
_show = false;
}
}
Show 和 Hide 方法现在可以工作了,尽管所改变的只是添加了一个 RenderFragment。
<Test1Component @ref="_test1Component">Test1Component</Test1Component>
<button type="button" @onclick="(() => { if (_test1Component != null) _test1Component.Hide(); })">Hide Test</button>
<button type="button" @onclick="(() => { if (_test1Component != null) _test1Component.Show(); })">Show Test</button>
@code{
Test1Component _test1Component;
}
我怀疑 Blazor 在后台以某种方式注册此组件,因为 RenderFragment,在内部跟踪其状态并在更新时自动触发 StateHasChanged。
那么问题来了,在这种情况下,您是使用StateHadChanged 方法来更新状态还是在包含 RenderFragment 时依赖自动维护的状态?
有谁知道 1. 为什么会这样?和 2. 幕后实际发生了什么以使其发挥作用?我只是通过非常有条理地试图找出从头开始触发更新的最佳方法才注意到这一点,但是从 Blazor 开始它会导致一些混乱,因为某些组件可以正常工作,而其他组件则不会没有 StateHasChanged 存在被称为,这种行为有时似乎是随机的,没有韵律或理由。显然,现在开始明白为什么会发生这种情况了。
【问题讨论】: