C# 当ShouldRender被覆盖时,每个子级上的调用状态已分别更改
考虑到我有很多子组件C# 当ShouldRender被覆盖时,每个子级上的调用状态已分别更改,c#,blazor,blazor-server-side,.net-5,blazor-webassembly,C#,Blazor,Blazor Server Side,.net 5,Blazor Webassembly,考虑到我有很多子组件 <Parent> <Child ref="children[0]" /> <Child ref="children[1]"/> <Child ref="children[2]" /> </Parent> 然后 与在父组件上调用StateHasChanged相比,在每个子组件上单独调用StateHasChanged是否有任何性能差异或
<Parent>
<Child ref="children[0]" />
<Child ref="children[1]"/>
<Child ref="children[2]" />
</Parent>
然后
与在父组件上调用StateHasChanged相比,在每个子组件上单独调用StateHasChanged是否有任何性能差异或副作用?简单的回答是:使用什么策略并不重要,只会将虚拟DOM和RenderTree之间的差异传递给实际DOM。其他一切都只是执行代码 一个更完整但更复杂的答案: 首先,了解
IComponent
和ComponentBase
之间的区别。所有组件都必须实现IComponent
——它是渲染器用来与组件通信的接口ComponentBase
是IComponent
的Blazor实现,是Razor组件的默认基础组件
Razor标记组件被预编译成一个C#类。您可以在obj目录中看到它们
组件第一次通过其父级传递到渲染器时,请执行以下操作:
像任何标准C#对象一样被实例化
渲染器
将其添加到渲染树
RenderHandle
调用Attach
并传递它存储的组件aRenderHandle
Renderer
调用OnParametersSet
传递任何请求的参数
就是这样,正如IComponent
所定义的那样。对于从ComponentBase
继承的任何组件,标准众所周知的事件序列由OnParametersSet
启动,包括调用StateHasChanged
StateHasChanged
是一种ComponentBase
方法。它调用RenderHandle.Render
传递表示组件的RenderFragment
。RenderFragment
中的任何新组件都会经历上述循环。对于任何现有组件,渲染器:
检查组件是否有任何子组件-这些子组件可能有级联参数
检查组件的参数是否已更改。对于基本体,这很容易,但如果有任何对象,它会假定它们已更改
如果其中一个为true,它将调用组件上的OnParametersSet
,并传入相应的参数
RenderHandle.Render
在渲染队列上堆叠RenderFragment
。执行时,队列将更新渲染器持有的虚拟DOM,然后运行扩散引擎以发现任何DOM差异并将其传递给客户端,客户端将更新浏览器中的实际DOM
我尽量保持简洁,但是。。。。希望这有助于理解组件和渲染过程。我希望不会,因为整个想法是要有独立的组件。如果您需要在页面级别协调对StateHasChanged
的调用,那将是很糟糕的。这是一个非常开放的问题——当然存在差异——但是没有人能够说对性能的确切影响是什么,因为这取决于您如何编写组件以及组件的功能。可以说有一些明显的区别,比如在父级上调用SHC会将父级及其所有子级提交到渲染队列,而仅在每个子级上调用SHC不会提交父级进行渲染。一般来说,我试图让每个组件负责自己的渲染。在这种情况下,我在父级中没有任何UI,因此它永远不需要刷新。@MisterMagoo。。。是否确实对父组件调用StateHasChanged()会导致子组件重新呈现?如果级联或传递给子组件的参数没有变化,那么我认为调用StateHasChanged()是不可能的“在父组件上”表示所有子组件自动重新渲染。请确保选中了参数,但这是渲染的一部分batch@NeilW:即使参数未更改,但至少有一个非基本参数,子组件也会重新关联。见我的另一个问题: