天天看點

深入淺出 React 高階元件背景知識實作一個高階元件高階元件實戰與父元件差別開源的高階元件使用賞析總結參考

在開始講述高階元件前,我們先來回顧高階函數的定義:接收函數作為輸入,或者輸出另一個函數的一類函數,被稱作高階函數。對于高階元件,它描述的便是接受react元件作為輸入,輸出一個新的react元件的元件。

更通俗地描述為,高階元件通過包裹(wrapped)被傳入的react元件,經過一系列處理,最終傳回一個相對增強(enhanced)的react元件,供其他元件調用。

下面我們來實作一個最簡單的高階元件(函數),它接受一個react元件,包裹後然後傳回。

在其他元件裡,我們引用這個高階元件,用來強化它。

在這裡使用了<code>es7</code>裡的<code>decorator</code>,來提升寫法上的優雅,但是實際上它隻是一個文法糖,下面這種寫法也是可以的。

随後,觀察react元件樹發生了什麼變化,如圖所示,可以發現demo元件被hoc元件包裹起來了,符合了高階元件的預期,即元件是層層包裹起來的,如同洋蔥一樣。

深入淺出 React 高階元件背景知識實作一個高階元件高階元件實戰與父元件差別開源的高階元件使用賞析總結參考

但是随之帶來的問題是,如果這個高階元件被使用了多次,那麼在調試的時候,将會看到一大堆<code>hoc</code>,是以這個時候需要做一點小優化,就是在高階元件包裹後,應當保留其原有名稱。

我們改寫一下上述的高階元件代碼,增加了<code>getdisplayname</code>函數以及靜态屬性<code>displayname</code>,此時再去觀察<code>dom tree</code>。

深入淺出 React 高階元件背景知識實作一個高階元件高階元件實戰與父元件差別開源的高階元件使用賞析總結參考

此時,原本元件的名稱正确地顯示在了<code>dom tree</code>上。

這個簡單的例子裡高階元件隻做了一件事,那便是為被包裹的元件添加一個标題樣式。這個高階元件可以用到任何一個需要添加此邏輯的元件上,隻需要被此高階元件修飾即可。

由此可以看出,高階元件的主要功能是封裝并抽離元件的通用邏輯,讓此部分邏輯在元件間更好地被複用。

還是以上述例子為例,此高階元件僅僅隻是展示了我是标題這個名稱,但是為了更好的抽象,此标題應當可以被參數化,如下方式調用。

<code>withheader</code>需要被改寫成如下形式,它接受一個參數,然後傳回一個高階元件(函數)。

使用es6寫法可以更加簡潔。

如圖可以看到,傳入的參數已經反映在<code>dom tree</code>裡了。

深入淺出 React 高階元件背景知識實作一個高階元件高階元件實戰與父元件差別開源的高階元件使用賞析總結參考
柯裡化 curry 概念:隻傳遞函數的一部分參數來調用它,讓它傳回一個函數去處理剩下的參數。 函數簽名:fun(params)(otherparams) 應用:在react裡,通過柯裡化,我們可以通過傳入不同的參數來得到不同的高階元件。

屬性代理是最常見的高階元件的使用方式,上述描述的高階元件就是這種方式。它通過做一些操作,将被包裹元件的<code>props</code>和新生成的<code>props</code>一起傳遞給此元件,這稱之為屬性代理。

這種方式傳回的react元件繼承了被傳入的元件,是以它能夠通路到的區域、權限更多,相比屬性代理方式,它更像打入組織内部,對其進行修改。具體的可以參考附錄裡提供的連結進行深入學習。

上述高階元件為react元件增強了一個功能,如果需要同時增加多個功能需要怎麼做?這種場景非常常見,例如我既需要增加一個元件标題,又需要在此元件未加載完成時顯示loading。

使用<code>compose</code>可以簡化上述過程,也能展現函數式程式設計的思想。

組合 <code>compose</code> <code>compose</code>可以幫助我們組合任意個(包括0個)高階函數,例如<code>compose(a,b,c)</code>傳回一個新的函數<code>d</code>,函數<code>d</code>依然接受一個函數作為入參,隻不過在内部會依次調用<code>c,b,a</code>,從表現層對使用者保持透明。 基于這個特性,我們便可以非常便捷地為某個元件增強或減弱其特征,隻需要去變更compose函數裡的參數個數便可。 <code>compose</code>函數實作方式有很多種,這裡推薦其中一個<code>recompact.compose</code>,詳情見下方參考類庫。

高階元件作為一個函數,它可以更加純粹地關注業務邏輯層面的代碼,比如資料處理,資料校驗,發送請求等,可以改善目前代碼裡業務邏輯和ui邏輯混雜在一起的現狀。父元件則是ui層的東西,我們先前經常把一些業務邏輯處理放在父元件裡,這樣會造成父元件混亂的情況。為了代碼進一步解耦,可以考慮使用高階元件這種模式。

<code>recompact</code>提供了一系列使用的高階元件,可以增強元件的行為,可以利用此庫學習高階元件的寫法。

通過使用此庫提供的高階元件,可以友善地讓清單元素可拖動。

高階元件是<code>decorator</code>模式在<code>react</code>的一種實作,它可以抽離公共邏輯,像洋蔥一樣層層疊加給元件,每一層職能分明,可以友善地抽離與增添。在優化代碼或解耦元件時,可以考慮使用高階元件模式。

繼續閱讀