首页 > 其他分享 >Blazor组件生命周期

Blazor组件生命周期

时间:2023-02-08 10:59:05浏览次数:40  
标签:生命周期 StateHasChanged 调用 InvokeAsync 组件 Blazor 方法

 

 

 

 

SetParameterAsync

这个方法在组件运行后执行。参数们,也就是被标记了 Parameter 特性的参数在被设置以后,通过该方法的 ParameterView 参数传入进来。但是,标记了 [Parameter] 的参数这时还未得到从外面组件的赋值的结果。

 

OnInitialized / OnInitializedAsync

没有 Async 后缀的是异步方法,但结果都是一样的。但是执行顺序是:OnInitialized -> OnIntializedAsync

当经过了刚才的 SetParametersAsync 方法之后,就会立即执行这个方法,表示组件已经初始化完成。这里我们可以得到所有的被标记过 [Parameter] 参数的值。

Tips:这个时候界面是还没有开始被渲染,界面是空白状态,浏览器会有一个旋转图标,表示加载中,所以尽量避免在这一步编写长时间操作的代码,比如查询数据库,或者请求别的服务。

当页面通过超链接对本页面的组件进行跳转,则不会执行 OnInitialized 方法

OnParametersSet / OnParametersSetAsync

执行顺序依然是先同步后异步,即 OnParametersSet -> OnParametersSetAsync 。

这是组件生命周期中可能被重复调用的第一对方法。如果组件的[参数]属性都没有改变,那么组件将简单地闲置,直到它最终被销毁。但是,如果其父HTML标记中的任何参数被更改,那么这些方法将在组件状态更新后触发。这将导致 Blazor 重新计算组件的渲染树,然后执行 OnAfterRenderOnAfterRenderAsync 方法。

同样地,和 OnInitialized 方法一样,如果是同一组页面的组件,则不会执行 OnParametersSet 方法。参见上面的例子。

 

OnAfterRender / OnAfterRenderAsync

执行顺序为 OnAfterRender -> OnAfterRenderAsync

该方法会在渲染树工作完成后执行,即页面渲染结束。但该方法被执行一般会有以下情况:

  • 组件的[Parameter] 属性在父组件的HTML标记中被改变
  • 用户与组件进行了交互(例如鼠标点击)
  • 组件执行它的 StateHasChanged 方法来调用一个重新呈现。

该方法会有一个布尔值参数 firstRender,该参数只有在方法第一次在当前组件上被调用时才为 true,此后它将始终为 false

StateHasChanged

此方法不符合生命周期方法的资格,但它确实触发了组件生命周期中的另一个方法。在默认情况下,Blazor会检查它的状态是否在某些交互之后发生了改变(比如点击按钮)。

有时 Blazor 无法意识到状态的变化,例如何时被计时器触发。这时你需要手动调用 StateHasChanged 来通知 Blazor 某些参数已经被更改。表示向 Blazor渲染请求一个重新渲染,然后将触发 OnAfterRender 和OnAfterRenderAsync

Dispose

尽管严格来说这不是 ComponentBase 的生命周期方法之一,但如果一个组件实现了 IDisposable,那么 Blazor 将在组件从父组件的呈现树中移除后执行Dispose 方法。

要实现 IDisposable,我们需要在 razor 文件中添加 @implements IDisposable

Blazor中的StateHasChanged()InvokeAsync(StateHasChanged)

我知道调用StateHasChanged()方法会通知组件状态已更改,它应该re-render

然而,我也在其他人的代码中看到对await InvokeAsync(StateHasChanged)await
InvokeAsync(() => StateHasChanged())的调用,但我不太理解它与StateHasChanged()的比较,以及什么时候应该优先于另一个,以及为什么。

我能找到的唯一信息是Blazor文档的这一部分,上面写着:

在必须基于外部事件(如计时器或其他通知)更新组件的情况下,请使用InvokeAsync方法,该方法将分派到Blazor的同步上下文。

我不太明白。它只是说"…which分派到Blazor的同步上下文”,但我对此不太满意!什么是“Blazor的同步上下文”?

我尝试过在TimerElapsed事件中调用StateHasChanged()而不是InvokeAsync(StateHasChanged),它按预期工作,没有任何问题。我应该打电话给await
InvokeAsync(StateHasChanged)吗?!如果是,为什么呢?我觉得这里可能有一些我不知道的重要的细微差别。

我也见过类似InvokeAsync(() => InvokeAsync(Something))的电话,为什么?

另外,我有时也会看到InvokeAsync()没有await被调用,这怎么办?!

在计时器的已用事件中调用StateHasChanged()——而不是InvokeAsync(StateHasChanged),它按预期工作

那一定是在WebAssembly上。在Blazor服务器端尝试一下,我希望会出现一个异常。

核心问题是呈现和调用StateHasChanged都必须在主(UI)thread上进行。卷影DOM副本不是thread-safe

Blazorlife-cycle事件(OnInit、AfterRender、ButtonClick)都是在这个特殊的thread上执行的,因此在极少数需要StateHasChanged()的情况下,可以不使用InvokeAsync()调用它。

但是计时器不同,它是一个“外部事件”,因此您不能确定它将在正确的thread上执行。InvokeAsync()将工作委托给右边thread(它属于Blazor的同步上下文)。

但是blazorwebassembly只有1个thread,因此目前外部事件也在同步上下文中运行。这意味着当你做错事的时候你什么都不会注意到。直到有一天,当blazorwasm最终实现threads时,您的代码将失败。就像你的计时器实验一样。

什么是“Blazor的同步上下文”?

在.net中,同步上下文决定等待(之后)发生什么。不同的平台有不同的设置,Blazor synccontext非常类似于WinFormsWPF。主要是,默认值是.ConfigureAwait(true):在相同的thread上恢复。

我有时在blazorwasm代码中看到.ConfigureAwait(false),当我们得到threads时,它就会爆炸。

最后,await InvokeAsync(StateHasChanged)await InvokeAsync(() => StateHasChanged()只是关于C中的lambda,与Blazor无关。第一个简短的形式更有效一些。

我有时也看到InvokeAsync()没有await调用

这绝不是一个好主意,尽管它通常会奏效。把它当作一个错误。

标签:生命周期,StateHasChanged,调用,InvokeAsync,组件,Blazor,方法
From: https://www.cnblogs.com/stonechina/p/17100939.html

相关文章

  • Blazor子组件传递数据到父组件
    @page"/counter"<PageTitle>Counter</PageTitle><SubComponnenttest="returnDatas"></SubComponnent><h1>Counter</h1><prole="status">Currentcount:@curren......
  • JAVA WEB项目大文件上传下载组件
    ​ 最近遇见一个需要上传百兆大文件的需求,调研了七牛和腾讯云的切片分段上传功能,因此在此整理前端大文件上传相关功能的实现。在某些业务中,大文件上传是一个比较重要的......
  • 基于vue3的跑马灯组件|vue3-marquee
    vue3-marquee是Vue3的一个简单的跑马灯组件,可以创建可定制的跑马灯效果。该组件为您的内容使用插槽,提供多种配置选项来控制跑马灯的效果。安装//npmnpminstallv......
  • 界面组件DevExpress ASP.NET Core v22.2——支持.NET 6
    DevExpressASP.NETCore Controls使用强大的混合方法,结合现代企业Web开发工具所期望的所有功能。该套件通过ASP.NETRazor标记和服务器端ASP.NETCoreWebAPI的生产力和......
  • 认证组件 权限组件 频率组件 过滤排序 分页
    目录回顾认证组件认证组件的使用步骤注意:权限组件权限的使用频率组件使用步骤过滤排序继承APIView写内置过滤类的使用,继承GenericAPIView使用第三方django-filter实现过滤......
  • Vue组件间通讯方式
    总结Vue组件间通讯方式父子组件通讯父向子一般为props:在父组件内,子组件标签上写明传递参数的名字和值,在子组件内部用props声明,即可使用//子......
  • drf认证组件/权限/频率 排序组件 分页组件
    Drf认证组件eg:个别接口需要登录后才可以使用局部使用#需要编写一个认证类#在py文件中创建一个认证类的py文件authentication.py通过继承来编写:eg:登录验证from......
  • DRF - 过滤与排序、分页组件
    目录过滤与排序1.drf内置过滤类【继承GenericAPIView】导入内置过滤器-SearchFilterviews.py-搜索方式2.第三方过滤器导入模块这里用到了第三方模块django-filtersviews......
  • React.Component详细 API(生命周期)
    前言:几年不用react,已发生翻天覆地变化,比如生命周期的方法,现在重写学习,记录变化。  组件的生命周期每个组件都包含“生命周期方法”,你可以重写这些方法,以便于在运行......
  • drf权限组件 频率组件 过滤排序 分页
    1认证组件#以后,有的接口需要登录才能访问,有的接口,不等了就能访问 -登录认证的限制#写一个登录接口,返回token,以后只要带着token过来,就是登陆了,不带就是没有登录#......