iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 13
3
Modern Web

大內魔術 Blazor - 誰說前端一定要寫JS系列 第 13

魔術技巧 - 掌握元件生命週期

  • 分享至 

  • xImage
  •  

今天要來介紹的是元件的生命週期,了解生命週期才能在元件進行初始化和轉譯期間時執行額外的作業。


這邊先上流程圖,我們再來慢慢說明。

https://raw.githubusercontent.com/MMiooiMM/learn-blazor-in-30-days/master/figures/13/lifecycle-flow.png

可以看到觸發變更的時間點有三個,父元件渲染到子元件時,使用者行為導致的事件產生,以及父元件將其從渲染樹移除。

而我們能覆寫的生命週期方法有以下四個:

  • 元件初始化方法 (OnInitialized / OnInitializedAsync)

此時間點上,元件已從父元件接收到初始化的參數,只會在 SetParametersAsync 完成後執行一次,絕對不會再次執行。

而當元件屬於頁面元件,也就是使用了 @page 變成可路由元件,如果 URL 不變 blazor 就會重新使用該元件,也就是不會執行 OnInitialized/OnInitializedAsync 且不會觸發 IDisposable.Dispose

  • 設定參數之後 (OnParametersSet / OnParametersSetAsync)

此時間點上,元件已經初始化完成,當 OnInitialized/OnInitializedAsync 執行結束後會執行外,父元件重新渲染並提供新參數時,也會被呼叫。

提供新參數時如果是可變的類型,如自訂類型時,因為 blazor 無法知道參數的內部是否發生變化,所以一律視為已改變;但不可變的類型,則需要至少一個參數改變,才會重新渲染。

  • 防止 UI 重新渲染 (ShouldRender)

再提到 ShouldRender 之前,先提一下它上層的 StateHasChangedStateHasChanged 是不能異動的,用於通知元件其狀態已變更,且所有的 EventCallback 方法都會自動呼叫 StateHasChanged

如果想要避免使用者操作產生的渲染時,可以覆寫此方法來防止 UI 重新渲染,也就是可以確保渲染樹一定是從初始化產生的。

若想進一步了解可以參考ASP.NET Core Blazor WebAssembly 效能最佳做法 - 避免不必要的元件呈現

  • 元件呈現之後 (OnAfterRender / OnAfterRenderAsync)

此時間點上,元件已經完成渲染。此時 DOM 就已經畫好了,如果要使用第三方的 JavaScript 來存取 DOM,就能正確取得了。

而這方法有提供 firstRender 參數,代表是否為第一次渲染,可以確保有些動作只在初始化時執行一次即可。

元件處置

這邊要特別注意的是,如果在元件的生命週期中訂閱事件,請務必在元件移除時進行解除,可以透過實作 IDisposable 來正確釋放資源。

@implements IDisposable

...

@code {
  private EventHandler<FieldChangedEventArgs> fieldChanged;

  protected override void OnInitialized()
  {
    editContext = new EditContext(...);

    fieldChanged = (_, __) =>
    {
      // ...
    };

    editContext.OnFieldChanged += fieldChanged;
  }

  public void Dispose()
  {
    editContext.OnFieldChanged -= fieldChanged;
  }
}

以上就是元件生命週期的介紹,如果想看實際用法可以參考範例程式碼 - day13

感謝大家的閱讀,我們明天見。

參考資料
ASP.NET Core Blazor 生命週期
Component lifecycles
使用 IDisposable 的元件處置


上一篇
表單魔術 - 資料繫結與事件處理技巧
下一篇
魔術技巧 - 父子溝通問題
系列文
大內魔術 Blazor - 誰說前端一定要寫JS30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言