Blazor 组件生命周期方法 OnParametersSet 行为
Blazor component lifecycle method OnParametersSet behavior
我正在学习 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
被解雇了?根据official documentation,这个方法应该叫:
after component is initialized or when the parent component re-renders
None 这些是我的情况,IMO。
But if I update TestComponent2 value I see the same log.
当您更新 TestComponent2 的值时,将触发一个 UI 事件并调用 StateHasChanged 方法来通知组件其状态已更改并且应该重新呈现。当父组件重新渲染时,两个子组件都重新渲染:或者当父组件重新渲染时
您可以在父组件中测试(OnAfterRender 方法),每次更新 TestComponent2 的值时,父组件都会重新渲染。
注意:如果您在父组件中放置“DoNothing”按钮而不是 @onchange="() => { }"
,则预期会有相同的行为。
这一切都与RenderFragment委托属性ChildContent的使用有关,
没有它,这两个子组件的重新渲染将不会发生。也就是说,如果您不在组件中使用子内容,OnParametersSet 将仅针对状态已更改的子组件触发。
这里 a link github 的问题与您的问题类似...
我正在学习 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
被解雇了?根据official documentation,这个方法应该叫:
after component is initialized or when the parent component re-renders
None 这些是我的情况,IMO。
But if I update TestComponent2 value I see the same log.
当您更新 TestComponent2 的值时,将触发一个 UI 事件并调用 StateHasChanged 方法来通知组件其状态已更改并且应该重新呈现。当父组件重新渲染时,两个子组件都重新渲染:或者当父组件重新渲染时
您可以在父组件中测试(OnAfterRender 方法),每次更新 TestComponent2 的值时,父组件都会重新渲染。
注意:如果您在父组件中放置“DoNothing”按钮而不是 @onchange="() => { }"
,则预期会有相同的行为。
这一切都与RenderFragment委托属性ChildContent的使用有关, 没有它,这两个子组件的重新渲染将不会发生。也就是说,如果您不在组件中使用子内容,OnParametersSet 将仅针对状态已更改的子组件触发。
这里 a link github 的问题与您的问题类似...