在用 React 的時候,很容易遇到兩個不同的組件之間有很多的共用代碼象浑。目前的項目是當(dāng)時趕鴨子上架用的 React,很多的做法是復(fù)制組件 A 的代碼為組件 B逛绵,然后全局搜索替換昨凡。這樣的做法非常 low晌缘,可維護(hù)性非常差纠永,也是非常不負(fù)責(zé)任的领跛。腹侣。叔收。
所幸這段時間比較有空,所以想趕緊把之前挖的坑給填上傲隶。由于目前整個項目都是用 ES6饺律,第一步很自然的想到用繼承的方式來復(fù)用代碼。然而事實是嚴(yán)峻的跺株,項目中多半的組件是像下面這樣
// A.jsx
class A extends React.Component {
handleAdd () {
// 共用代碼
....
// 特定代碼
addXXA()
}
}
// B.jsx
class B extends React.Component {
handleAdd () {
// 共用代碼
....
// 特定代碼
addXXB()
}
}
最開始提到的搜索替換复濒,大部分就是在改這些特定代碼脖卖。也是因為這樣的代碼,在項目最先開始的時候巧颈,想不到比較好的復(fù)用方式畦木。當(dāng)然這個問題在 React 社區(qū)也是比較常見的,所以搜了下谷歌洛二,很快就能發(fā)現(xiàn)一個叫 mixin 的方案馋劈。
然而上天在給你開了一扇窗時,會把門給你關(guān)上晾嘶!React 已經(jīng)宣布 ES6 不支持 mixin 妓雾,而且官方還說了目前這種情況沒有其它替代方案。垒迂。械姻。
沒有替代方案,你還鼓勵大家用 ES6机断,而且我特么還信了楷拳!劇情到了這個時候,一般都會有個救世主出現(xiàn)吏奸。一個 React 核心團(tuán)隊的成員在 gist 上面放出了一段代碼 欢揖,取名為 Higher Order Component,嗯奋蔚,挺帥氣的她混。
為了表示這個并不是 React 官方的意見,你直接復(fù)制粘貼這段代碼就會發(fā)現(xiàn)泊碑,根本就運行不了坤按。
運行不了,你放上去干嘛馒过。臭脓。。不過仔細(xì)看這段代碼腹忽,你就會發(fā)現(xiàn)都是小問題来累。那段 gist 下面有很多網(wǎng)友的評論,四六級沒過的可以當(dāng)做練練閱讀理解留凭。怕有些人真的沒辦法改這段代碼佃扼,React 社區(qū)的一個大神 Dan 也給出了解決方法。當(dāng)然別問我為什么知道真的能解決蔼夜!
Higher Order Component 的中文名稱叫高階組件(怎么有股濃濃的高數(shù)味)兼耀。后來才發(fā)現(xiàn),這個是借鑒于 Higher Order Function (高階函數(shù)),還以為外國銀都這么會取名字瘤运。
看下維基百科上面對于 Higher Order Function 的定義
A higher-order function is a function that does at least one of the following:
- takes one or more functions as arguments
- returns a function as its result
所以對應(yīng)的窍霞,Higher Order Component 的定義就是
一個函數(shù),接收一個或多個組件作為參數(shù)拯坟,返回新的組件但金。
現(xiàn)在就用 Higher Order Component 來改下文章最開始的代碼。
// Enhance.js
export const Enhance = (ComposedComponent, handleAdd) => class extends Component {
handleAdd () {
// 共用代碼
...
// 特定代碼
handleAdd()
}
render () {
return (
<ComposedComponent
{...this.props}
handleAdd={this.handleAdd}
/>
)
}
}
// A.jsx
class A extends React.Component {
}
export default Enhance(A, addXXA)
// B.jsx
class B extends React.Component {
}
export default Enhance(B, addXXB)
嗯郁季,看起來還不錯冷溃,可以比較優(yōu)雅地解決代碼復(fù)用的問題。用 Higher Order Component 還可以解決 React 生命周期的問題梦裂,更詳細(xì)的用法可以參考
英文好的可以看下這篇
這篇文章原本打算好好寫下 Higher Order Component 的用法似枕,沒想到寫了一半畫風(fēng)突變。好吧年柠,只能寫成科普文凿歼,順便給大家娛樂娛樂,不過還是希望能給遇到這個問題的人帶來幫助冗恨。