背景部分是我對(duì)高階組件的理解,確保在繼續(xù)具體問(wèn)題前,我們的理解是一致的。
背景:
React中高階組件是一個(gè)普通的函數(shù)。之所說(shuō)它是“普通”的函數(shù),是想和組件類區(qū)分開(kāi),因?yàn)镴S中的類本質(zhì)上也是函數(shù)。所以高階組件雖然叫組件,但它并不是普通意義的 React 組件,而是一個(gè)函數(shù)。
這個(gè)函數(shù)接收一個(gè)React 組件類(姑且稱為“被包裝組件”)或其他可選參數(shù),并返回一個(gè)新的組件類(姑且稱為“增強(qiáng)型組件”)。所以你可以認(rèn)為高階組件是一個(gè)組件工廠函數(shù)。返回的組件類在 render 時(shí)往往使用“被包裝組件”進(jìn)行渲染。
其實(shí),高階組件的函數(shù)體的實(shí)現(xiàn)大部分都是“增強(qiáng)型組件”的實(shí)現(xiàn),在實(shí)現(xiàn)中利用傳遞給高階組件的參數(shù)定制化“增強(qiáng)型組件”的實(shí)現(xiàn)。
“增強(qiáng)型組件”是“被包裝組件”的容器組件。所以 React 文檔上說(shuō)
You can think of HOCs as parameterized container component
definitions.(你可以把 HOC 看作是參數(shù)化的容器組件的定義)
具體問(wèn)題:
那么問(wèn)題來(lái)了,既然 hoc 可看做是參數(shù)化的容器組件的定義,那么 hoc 的獨(dú)特意義何在呢?如果需要對(duì)一個(gè) React 組件進(jìn)行功能增強(qiáng),我給它在外面套一層容器組件不就行了嗎?同時(shí)容器組件也可以通過(guò)接收props 來(lái)進(jìn)行實(shí)現(xiàn)過(guò)程的定制化,props中也可包含組件類,即“被包裝組件”。高階組件對(duì)容器組件進(jìn)行定制化實(shí)現(xiàn)只不過(guò)是通過(guò)函數(shù)的參數(shù),這和容器組件本身使用 props 來(lái)定制化沒(méi)有本質(zhì)區(qū)別。
拿 React 文檔中的例子來(lái)說(shuō),文檔中將 withSubscription 實(shí)現(xiàn)為一個(gè)高階組件。那么我覺(jué)得就這個(gè)例子來(lái)說(shuō),withSubscription 實(shí)現(xiàn)為一個(gè)普通的 React 組件效果也是完全一樣的。只要把 withSubscription 的函數(shù)參數(shù)變?yōu)?WithSubscription 這個(gè)普通 React 組件的 props 即可。WithSubscription 的實(shí)現(xiàn)也就直接是“被包裝組件”的容器組件的實(shí)現(xiàn)了,而無(wú)需像 withSubscription 那樣返回一個(gè)容器組件類。
文檔上舉的例子確實(shí)說(shuō)明了高階組件應(yīng)用的情境,但就這個(gè)例子而言,似乎不是非高階組件不可。那么,高階組件這種設(shè)計(jì)模式的獨(dú)特性在哪里,意義是什么?
如果需要對(duì)一個(gè) React 組件進(jìn)行功能增強(qiáng),我給它在外面套一層容器組件不就行了嗎?同時(shí)容器組件也可以通過(guò)接收props 來(lái)進(jìn)行實(shí)現(xiàn)過(guò)程的定制化,props中也可包含組件類,即“被包裝組件”。高階組件對(duì)容器組件進(jìn)行定制化實(shí)現(xiàn)只不過(guò)是通過(guò)函數(shù)的參數(shù),這和容器組件本身使用 props 來(lái)定制化沒(méi)有本質(zhì)區(qū)別。
其實(shí)你說(shuō)的這就是高階組件的實(shí)現(xiàn)方式了。高階組件只是將組件(函數(shù))作為參數(shù)的一個(gè)函數(shù)罷了。更加 fp。一般高階函數(shù)什么的,不就是因?yàn)槟芙邮芎瘮?shù)作為參數(shù)么。所以取名為高階。。。比如react-redux connect 其實(shí)就是高階組件。 寫(xiě)法上來(lái)看,你覺(jué)得const App = <Enhance><Main/></Enhance>
好還是const App = Enhance(Main)
更好?
比如說(shuō)你要給每個(gè)組件(Table、Slider等等)外面都加個(gè)Loading
如果說(shuō)照著題主的想法,可能是給Table或者Slider外面套一層方法,最后返回個(gè)新組件就得了
但這樣Table或者Slider本身就寫(xiě)死了而不是一個(gè)靈活的參數(shù),如果我下次有個(gè)Table1呢,又得寫(xiě)一遍
這還不算,萬(wàn)一我這是個(gè)狀態(tài)深沉的Loading呢...
具體的情況可以去看看antd的Form,如果不抽象一下真的欲仙欲死
這玩意就是為了少寫(xiě)重復(fù)的代碼的,獨(dú)特性倒還真沒(méi)覺(jué)得
題主也說(shuō)了這是個(gè)設(shè)計(jì)模式,沒(méi)碰上實(shí)際場(chǎng)景的時(shí)候它的確沒(méi)用,并不是什么非它不用的東西
碰見(jiàn)了,知道有這個(gè)東西了,那問(wèn)題就會(huì)簡(jiǎn)單很多了
以上是我云出來(lái)的,并沒(méi)有實(shí)際操作過(guò),只是知道有這么個(gè)東西
我實(shí)際操作過(guò)的所謂的“高階組件”反而是用在了以下場(chǎng)景:
原先的組件不成熟,但又急著上線,后來(lái)有時(shí)間了要重寫(xiě)
改成成熟版本以后和原先版本用法差異很大,但又要兼容之前項(xiàng)目的用法
于是干脆組件本體改個(gè)名字,然后外面包一層跟原先一樣的名字的皮,就這么將就用著先的這么一種“被動(dòng)高階”
仔細(xì)查了下,我發(fā)現(xiàn)對(duì)高階組件的理解還是片面了
北大青鳥(niǎo)APTECH成立于1999年。依托北京大學(xué)優(yōu)質(zhì)雄厚的教育資源和背景,秉承“教育改變生活”的發(fā)展理念,致力于培養(yǎng)中國(guó)IT技能型緊缺人才,是大數(shù)據(jù)專業(yè)的國(guó)家
達(dá)內(nèi)教育集團(tuán)成立于2002年,是一家由留學(xué)海歸創(chuàng)辦的高端職業(yè)教育培訓(xùn)機(jī)構(gòu),是中國(guó)一站式人才培養(yǎng)平臺(tái)、一站式人才輸送平臺(tái)。2014年4月3日在美國(guó)成功上市,融資1
北大課工場(chǎng)是北京大學(xué)校辦產(chǎn)業(yè)為響應(yīng)國(guó)家深化產(chǎn)教融合/校企合作的政策,積極推進(jìn)“中國(guó)制造2025”,實(shí)現(xiàn)中華民族偉大復(fù)興的升級(jí)產(chǎn)業(yè)鏈。利用北京大學(xué)優(yōu)質(zhì)教育資源及背
博為峰,中國(guó)職業(yè)人才培訓(xùn)領(lǐng)域的先行者
曾工作于聯(lián)想擔(dān)任系統(tǒng)開(kāi)發(fā)工程師,曾在博彥科技股份有限公司擔(dān)任項(xiàng)目經(jīng)理從事移動(dòng)互聯(lián)網(wǎng)管理及研發(fā)工作,曾創(chuàng)辦藍(lán)懿科技有限責(zé)任公司從事總經(jīng)理職務(wù)負(fù)責(zé)iOS教學(xué)及管理工作。
浪潮集團(tuán)項(xiàng)目經(jīng)理。精通Java與.NET 技術(shù), 熟練的跨平臺(tái)面向?qū)ο箝_(kāi)發(fā)經(jīng)驗(yàn),技術(shù)功底深厚。 授課風(fēng)格 授課風(fēng)格清新自然、條理清晰、主次分明、重點(diǎn)難點(diǎn)突出、引人入勝。
精通HTML5和CSS3;Javascript及主流js庫(kù),具有快速界面開(kāi)發(fā)的能力,對(duì)瀏覽器兼容性、前端性能優(yōu)化等有深入理解。精通網(wǎng)頁(yè)制作和網(wǎng)頁(yè)游戲開(kāi)發(fā)。
具有10 年的Java 企業(yè)應(yīng)用開(kāi)發(fā)經(jīng)驗(yàn)。曾經(jīng)歷任德國(guó)Software AG 技術(shù)顧問(wèn),美國(guó)Dachieve 系統(tǒng)架構(gòu)師,美國(guó)AngelEngineers Inc. 系統(tǒng)架構(gòu)師。