gpt4 book ai didi

blazor - 我应该何时调用 StateHasChanged 以及 Blazor 何时自动拦截某些更改?

转载 作者:行者123 更新时间:2023-12-02 04:23:30 24 4
gpt4 key购买 nike

我很难理解什么时候应该打电话 StateHasChanged()当 Blazor 拦截到某些内容发生更改时,必须重新渲染。

我创建了一个示例项目,其中包含一个按钮和一个名为 AddItem 的自定义组件。该组件包含一个带有红色边框的 div 和一个按钮。

我的期望:我希望当用户单击索引页面中包含的按钮时,AddItem 的 div 将显示。然后我想在用户单击 AddItem 的按钮时隐藏它。

注意: AddItem 不会公开它 _isVisible外面的标志,而是包含 Show()方法。所以AddItems.Show()单击索引按钮时将调用。

测试:

  1. 我点击 Index 的点击按钮,然后点击方法 Open()AddItem.Show()被调用。旗帜_isVisible设置为true但没有任何反应,索引的 ShouldRender()被调用。

    控制台输出:

    • 渲染索引
  2. 我已修改AddItem.Show()public void Show() {_isVisible = true; StateHasChanged();} 。现在,AddItem 的 div 按预期显示和隐藏。

    控制台输出:

    • 渲染 AddItem(1° 单击索引按钮)
    • 渲染索引(1° 单击索引按钮)
    • 渲染 AddItem(2° 单击 addItem 的关闭按钮)
  3. 我已修改<AddItem @ref="AddItem" /><AddItem @ref="AddItem" CloseEventCallback="CallBack" /> ,删除StateHasChanged来自 AddItem 的 Show()方法。现在,AddItem 的 div 按预期显示和隐藏。

Based on Test 3: Why I don't have to explicit StateHasChanged if I set AddItem's CloseEventCallback to any parent's method? I'm having a hard time understanding it because AddItem doesn't invoke CloseEventCallback anywhere.

When Blazor understands that something is changed so it must be re-render?

我的示例代码(如果您想尝试的话)。

我的 Index.razor

<AddItem @ref="AddItem" />
<button @onclick="Open">click</button>
@code {
AddItem AddItem;

public void Open()
{
AddItem.Show();
}

public void CallBack()
{
}

protected override bool ShouldRender()
{
Console.WriteLine("Render INDEX");
return base.ShouldRender();
}
}

我的 AddItem 组件

@if (_visible)
{
<div style="width: 100px; height: 100px; border: 1px solid red">testo</div>
<button @onclick="Close">close</button>
}

@code {
private bool _visible = false;

[Parameter] public EventCallback<bool> CloseEventCallback { get; set; }

public void Show()
{
_visible = true;
}

public void Close()
{
_visible = false;
}

protected override bool ShouldRender()
{
Console.WriteLine("Render ADDITEM");
return base.ShouldRender();
}
}

最佳答案

一般来说,StateHasChanged()方法会在UI事件触发后自动调用,例如,单击按钮元素后,将引发单击事件,并且 StateHasChanged() 方法是自动调用以通知组件其状态已更改并且应该重新渲染。

首次访问 Index 组件时。先渲染父组件,再渲染父组件渲染它的 child 。

每当单击“打开”按钮时,索引组件就会重新呈现(这是因为事件的目标是父组件,默认情况下会重新渲染(无需使用 StateHasChanged)。但 child 却不然,他不知道自己的状态已经改变。为了让 child 意识到他的状态已经改变了,应该重新渲染,您应该添加对 StateHasChanged 方法的调用在 Show 方法中手动。现在,当您单击“打开”按钮时,子组件是首先重新渲染,然后其父级接下来重新渲染。现在红色 div 变得可见。

单击“关闭”按钮隐藏红色 div。这次只有子组件重新渲染(这是因为事件的目标是子组件,默认会重新渲染),但不是父级。

此行为是正确的并且是有意设计的。

如果从 AddItem.Show 方法中删除对 StateHasChanged 方法的调用,请定义此属性:[Parameter] public EventCallback<bool> CloseEventCallback { get; set; } ,并添加父组件中的组件属性,用于为此属性分配值,如下所示: <AddItem @ref="AddItem" CloseEventCallback="CallBack" /> ,你会发现外表没有任何变化,但这次单击“打开”按钮时重新渲染的顺序首先是父级重新渲染,然后子进程重新渲染。这准确地描述了您发现的问题在评论中的问题中:

So, why my test 3 worked as expected even if CloseEventCallback isn't invoked anywhere?

你是对的......在进行进一步调查之前我无法真正解释这种行为。 我会尽力查明发生了什么事,然后告诉你。

AddItem's close method invoke the CloseEventCallback to advise the parent that it should re-render.

注意:您的代码使用 bool 类型说明符定义 CloseEventCallback,因此您必须定义一个方法 在具有 bool 参数的父组件中。当您调用 CloseEventCallback“委托(delegate)”时 您实际上调用了 Index.Callback 方法,并且应该向其传递一个 bool 值。当然,如果你通过了 一个组件的值,您希望它重新渲染,以便可以在 UI 中看到新的状态。这就是EventCallback 提供的功能:虽然事件是在子组件中触发的,它的目标是父组件,这会导致父组件重新渲染。

I am wondering why a parent component should re-render itself if one of the subscribed EventCallback is invoked?

这正是我在上一段中试图解释的内容。 EventCallback类型是专门为了解决事件目标的问题而设计的,将事件路由到组件 其状态已更改(父组件),并重新渲染它。

关于blazor - 我应该何时调用 StateHasChanged 以及 Blazor 何时自动拦截某些更改?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60096040/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com