Blazor组件生命周期方法OnParametersSet行为

时间:2020-07-21 05:19:46

标签: blazor blazor-webassembly

我正在学习Blazor,并试图弄清楚组件生命周期方法的工作原理。

在WASM项目中,我创建了一个简单的组件:

public class TestComponent : ComponentBase
{
    [Parameter]
    public string Id { get; set; }

    [Parameter]
    public RenderFragment ChildContent { get; set; }

    protected override void OnParametersSet()
    {
        base.OnParametersSet();

        Console.WriteLine($"({Id}) {nameof(OnParametersSet)}()");
    }

    protected override void BuildRenderTree(RenderTreeBuilder builder)
    {
        base.BuildRenderTree(builder);

        Console.WriteLine($"({Id}) {nameof(BuildRenderTree)}()");
        builder.AddContent(0, this.ChildContent);
    }
}

并在页面上添加了此组件的2个实例:

<TestComponent Id="TestComponent1">
    <input class="input" type="text" value="" />
</TestComponent>

<TestComponent Id="TestComponent2">
    <input class="input" type="text" value="" @onchange="() => { }" />
</TestComponent>

现在,当页面加载时,我在浏览器控制台中看到此日志:

blazor.webassembly.js:1 (TestComponent1) OnParametersSet()
blazor.webassembly.js:1 (TestComponent2) OnParametersSet()
blazor.webassembly.js:1 (TestComponent1) BuildRenderTree()
blazor.webassembly.js:1 (TestComponent2) BuildRenderTree()

这是预期的,因为刚刚创建了组件。如果我更新TestComponent1的值,什么都不会发生。

但是,如果我更新TestComponent2值,则会看到相同的日志。我猜这是因为TestComponent2附加了事件处理程序,这导致组件每次都更新。我遇到了以下问题:

  • 为什么更新TestComponent2值会触发TestComponent1的生命周期方法?它们是如何关联的?

  • 为什么OnParametersSet被解雇?根据{{​​3}},此方法应称为:

组件初始化后或父组件重新渲染时

IMO都不是我的情况。

1 个答案:

答案 0 :(得分:2)

But if I update TestComponent2 value I see the same log.

当您更新TestComponent2的值时,将触发UI事件,并调用StateHasChanged方法以通知组件其状态已更改并且应重新呈现。当父组件重新渲染时,两个子组件都重新渲染:或父组件重新渲染时

您可以在父组件(OnAfterRender方法)中进行测试,每次更新TestComponent2的值时,父组件都会重新呈现。

注意:如果在父组件中放置一个“ DoNothing”按钮而不是@onchange="() => { }",则预期会出现相同的行为。

所有这些都与RenderFragment委托属性ChildContent的使用有关, 没有它们,将不会重新渲染两个子组件。也就是说,如果您不使用组件中的子内容,则OnParametersSet仅针对状态已更改的子组件触发。

a link到github的问题,与您的问题类似...