【问题标题】:Blazor weirdness with ChildContent RenderFragmentChildContent RenderFragment 的 Blazor 怪异
【发布时间】: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;
    }
}

在另一个组件中使用时,调用 ShowHide 不会做任何事情:

<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() 添加到ShowHide 方法中。但是,如果我们将实现更改为包含 RenderFragmentShowHide 方法就会神秘地开始工作。

@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;
    }
}

ShowHide 方法现在可以工作了,尽管所改变的只是添加了一个 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 存在被称为,这种行为有时似乎是随机的,没有韵律或理由。显然,现在开始明白为什么会发生这种情况了。

【问题讨论】:

    标签: blazor blazor-server-side


    【解决方案1】:

    当您的组件没有Parameters 时,渲染器将正确假设没有任何更改,并且不会在渲染期间因单击button 而重新渲染它

    添加 RenderFragment 参数会强制 Blazor 使用 - 它必须进行渲染,因为它无法检测参数是否已更改。

    调用子组件的公共方法的做法是可疑的 - 如果您只包含一个参数,例如 bool Hide 并从父组件中设置它,一切都会正常工作。

    【讨论】:

      猜你喜欢
      • 2021-01-29
      • 1970-01-01
      • 1970-01-01
      • 2020-06-17
      • 2021-05-29
      • 2023-03-28
      • 2021-07-11
      • 2021-11-09
      • 1970-01-01
      相关资源
      最近更新 更多