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

2024-03-15

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

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

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

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

Tests:

  1. 我单击索引的单击按钮,然后单击方法Open() and AddItem.Show()被调用。旗帜_isVisible被设定为true但什么也没发生,索引的ShouldRender()被调用。

    控制台输出:

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

    控制台输出:

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

基于测试 3:为什么我不必明确StateHasChanged如果我设置 AddItem 的CloseEventCallback有哪位家长有方法吗?我很难理解它,因为 AddItem 不调用CloseEventCallback任何地方。

and

当 Blazor 了解到某些内容已更改因此必须重新渲染时?

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

我的索引.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 组件时。先渲染父组件,再渲染父组件 渲染它的孩子。

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

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

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

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

那么,为什么即使没有在任何地方调用 CloseEventCallback,我的测试 3 仍能按预期工作?

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

AddItem 的 close 方法调用 CloseEventCallback 来通知父级它应该重新呈现。

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

我想知道为什么如果调用订阅的 EventCallback 之一,父组件应该重新渲染自身?

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

我应该何时调用 StateHasChanged 以及 Blazor 何时自动拦截某些更改? 的相关文章

  • 在 Blazor 组件中使用带有继承的泛型类型

    我正在尝试在 Blazor 中创建一个 通用列表 组件 并希望该组件能够接受从基类派生的任何对象 我的代码目前如下 基类 public class Model PK for the record Key public int Id get
  • C# 修改身份或添加声明

    应用程序是 Blazor Server NET Core 5 0 我正在使用 NET Core 的身份系统 但遇到了问题 我希望将这个人的名字与身份一起存储 以便我可以轻松地调用它 目前我有一个类覆盖基本身份 public class Ap
  • 为什么 Blazor 应用在​​任何页面重新加载时都会显示错误

    我正在使用 Blazor 技术开展项目 我有时需要使用一些 JS 代码 并且需要在每个页面中包含不同的 js 文件 据我所知 唯一的方法是使用 JS 函数和 Blazor JS 调用添加它 所以我所做的是 在 Host razor 中 fu
  • Blazor - 如何动态创建组件

    我想测试是否可以动态创建 Blazor 组件 我找不到任何方法来做到这一点 我尝试了一些在上面找到的动态内容这个链接 https learn blazor com pages dynamic content 但最终还没有得到任何结果 根据对
  • 获取 DbContext 中当前登录的用户

    出于审计目的 我尝试在 DbContext 中获取当前登录的用户 不过我对此有一些问题 需要考虑以下几点 在 Blazor Server 中我们必须使用 AddDbContextFactory IHttpContextAccessor 在部
  • Razor Pages 与服务器端 Blazor

    用于服务器端 Web 应用程序 就像过去的美好时光一样 Blazor https learn microsoft com en us aspnet core blazor view aspnetcore 3 1旨在提供流行 JavaScri
  • Blazor RenderFragment 到字符串

    我正在开发一个代码块组件 Net 6 Blazor wasm 我需要显示RenderFragment as string并在我的 html 中渲染该组件 这是我的代码块组件 pre class language html code clas
  • 如何在docker镜像中运行signalr blazor客户端的StartAsync连接?

    我创建了默认的 blazor 服务器端应用程序 然后添加Microsoft AspNetCore SignalR Client and ChatHub班级 然后编辑startup cs文件 添加services AddSignalR and
  • 有人可以解释 Blazor 组件标签的各种语法吗

    在我的 razor 文件中 我有这些标签 只是一个示例 它们有效 但我无法向自己解释各种语法背后的原因
  • BlazorWebView 内的 .NET MAUI Xaml

    我正在完全使用 Blazor 构建我的应用程序 一切都发生在我的 BlazorWebView 内 是否可以使用类似的东西RefreshView在 razor 文件中 我知道我可以实例化一个ContentView从代码后面但是我可以将其实现到
  • 有没有办法在 Blazor 中隐藏 div?

    我正在使用 Blazor 并且想在按下导航栏切换器图标时隐藏侧边栏 列表项崩溃了 但问题是 div 仍然存在 div class page div class sidebar div class nav top row pl 4 navba
  • 如何通过 HttpContext 访问 Blazor Server .Net 6 中的 cookie?

    不幸的是 有关在 Blazor Server 中访问 c ookie 的教程和之前的 StackOverflow 答案似乎在新的 Net 版本中变得无效 例如 我无法获得以下任一答案 根据 net 6 中没有的评论来判断 如何在服务器端 B
  • 在 Blazor 中读取和显示嵌套类/表中的数据的最佳方法是什么?

    主要目标 我正在创建一个 Blazor 应用程序 它将一次显示报告的一个段落 用户需要单击某个按钮才能转到报告的下一段 我需要创建一个数据库 其中包含段落 节标题和文档的表格 我的问题 我的问题与数据库部分以及如何从数据库读取数据的方式有关
  • Blazor 与 Razor

    随着 Blazor 的发明 我想知道这两种语言之间是否存在显着的效率 无论是在代码创建方面还是在代码的实际编译 执行方面 https github com SteveSanderson Blazor https github com Ste
  • 如何使用 blazor 前端 http 请求附加令牌

    我使用 blazor 作为前端 api 已完成 JWT 配置 前端可以创建用户帐户并登录API 但现在我的前端httpclient没有设置JWT令牌 所以如果我在Api控制器中设置 授权 前端将无法访问它 api程序代码如下 builder
  • 如何从代码后面的 Blazor WebAssembly 项目打开浏览器窗口/选项卡:

    我正在将 UWP 应用程序转换为托管 ASP NET Core 的 Blazor WebAssembly 我的标记代码位于 Index razor 中 后面的代码位于 Index razor cs 中 在 UWP 项目中 我通过 oncli
  • Wasm DOM 访问和引用类型

    我一直非常密切地关注 WebAssembly 的路线图 特别是调用 JS 互操作的性能影响 作为本次活动的一部分参考类型提案 https github com WebAssembly reference types blob master
  • OnAfterRenderAsync 未触发

    我试图找出为什么我无法在 Blazor 中获取 OnAfterRenderAsync 方法 在尝试了多种选项并查看 Microsoft 文档后 我似乎找不到解决方案 我确信我错过了一些东西 但我无法弄清楚问题是什么 在下面的代码中 OnIn
  • 解析 JWT 令牌以仅获取有效负载内容,无需 C# 或 Blazor 中的外部库

    我正在使用 Blazor 编写可以访问 JWT 的客户端应用程序 我想知道一种简单的方法来读取令牌有效负载内容而不添加额外的依赖项 因为我不需要其他信息 也不需要验证令牌 我认为解析有效负载内容应该足够简单 只需将其写入方法即可 JwtTo
  • dotnet.timezones.blat 返回 404 - 文件存在 - blazor 部署 [重复]

    这个问题在这里已经有答案了 我正在使用 Visual Studio 2022 wasm 托管站点项目 默认样板 我将其发布到 iis 服务器 但出现以下错误 我不知道为什么会发生这样的错误 我可以在框架文件夹中看到文件 doenet tim

随机推荐