Blazor - SetParameters - 为啥字符串参数绑定的行为与复杂类型不同
Posted
技术标签:
【中文标题】Blazor - SetParameters - 为啥字符串参数绑定的行为与复杂类型不同【英文标题】:Blazor - SetParameters - why string parameter binding behaves differently from a complex typeBlazor - SetParameters - 为什么字符串参数绑定的行为与复杂类型不同 【发布时间】:2021-08-20 07:50:31 【问题描述】:考虑带有字符串参数和复杂类型参数的子组件。
<Child Name="@strProperty" />
<Child Model="@compelexType" />
假设两个参数都没有改变,在父组件上调用 StateHasChanged 会导致具有复杂参数的子组件重新渲染,而不是字符串参数。
查看此演示:https://blazorrepl.com/repl/wbYguGuA515uMYR742
你如何解释不同的行为?
【问题讨论】:
Docs: "如果满足以下任一条件,则从 ComponentBase 继承的组件会因参数更新而跳过重新渲染:...所有参数值都是已知的不可变 primitive类型,例如 int、string、DateTime 和 自从设置了上一组参数后没有改变,..." 我会接受这个作为答案 【参考方案1】:这本身不是一个答案,我只是需要比评论更多的空间。
我认为引用的文档不能完全解释观察到的结果。
文件指出:
默认情况下,Razor 组件继承自 ComponentBase 基类,其中包含在以下时间触发重新渲染的逻辑:
-
从父组件应用一组更新的参数后。
为级联参数应用更新值后。
在通知事件并调用其自己的事件处理程序之一之后。
在调用其自己的 StateHasChanged 方法后(请参阅 ASP.NET Core Razor 组件生命周期)。
这些都是内部操作。前两个发生在组件上调用 SetParametersAsync
之后。最后两个来自组件内部的操作。
任何子组件活动,例如重新渲染,都是由Renderer
调用SetParametersAsync
触发的,而不是直接由父组件触发。 Renderer
根据检测到的对任何子组件 Parameter
的更改做出此决定。所以发生重新渲染的原因是因为Renderer
决定它是一个对象而不是原始类型,与ComponentBase
无关。
为了证明这一点,我基于IComponent
而不是ComponentBase
编写了一个非常基本的组件。它看起来像这样:
using Blazor.Starter.Data;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Rendering;
using System.Threading.Tasks;
namespace Blazor.Starter.Components.TestComponents
public class ObjectTest : IComponent
[Parameter] public DataModel Model get; set;
[Parameter] public int Value get; set;
private RenderHandle _renderHandle;
private int _renders;
public void Attach(RenderHandle renderHandle)
_renderHandle = renderHandle;
public Task SetParametersAsync(ParameterView parameters)
parameters.SetParameterProperties(this);
_renders++;
this.Render();
return Task.CompletedTask;
public void Render()
=> _renderHandle.Render(RenderComponent);
private void RenderComponent(RenderTreeBuilder builder)
builder.OpenElement(0, "div");
builder.AddContent(1, $"Rendered _renders");
builder.CloseElement();
如果您在父级SetParametersAsync
中设置Model
,则如果您只设置Value
,则不会。结果一样。
【讨论】:
【参考方案2】:Documentation:
如果满足以下任一条件,则从
所有参数值都是已知的不可变原始类型,例如ComponentBase
继承的组件会因参数更新而跳过重新渲染:int
、string
、DateTime
和自从设置了上一组参数以来没有改变。 组件的ShouldRender
方法返回false
。
【讨论】:
【参考方案3】:正如@GSerg 在评论中所说:这是因为原始属性没有改变,所以它没有更新。
【讨论】:
以上是关于Blazor - SetParameters - 为啥字符串参数绑定的行为与复杂类型不同的主要内容,如果未能解决你的问题,请参考以下文章
如何修复 Android.harware.Camera 中的 setParameters 失败?
Android调用camera错误setParameters failed深层解析
Camera setParameters(), getParameters(),unlock()三个方法之间的限制关系
java mock http_Java MockHttpServletRequest.setParameters方法代码示例