使用recompose給React開發加點料

高階組件的基本原理想必大家都已知曉,就如題圖一樣,將業務組件一層層包括起來便是高階組件最直接的認知。如果還不是很清晰,可以先閱讀一下筆者先前的入門文章。

道理大家都懂,可是在項目內,到底該如何開始使用高階組件呢?如果你缺乏靈感,不妨來了解一下recompose,它提供了一系列小而美的高階函數,可以簡化我們平常編寫的代碼,現在就讓我們一起來體驗一番吧。

開胃菜

compose可以將多個高階組件組合起來,例如:

const composedHoc = compose(hoc1, hoc2, hoc3)composedHoc(BaseComponent)

實際上等價於

hoc1(hoc2(hoc3(BaseComponent)))

使用高階組件時,一個組件往往效果不大,多個之間相互配合,會有奇妙效果湧現。

情景一:展示哪一個?

有些時候,你需要根據後端返回值來做決策,例如展示Loading組件,之前你可能會將這部分判斷寫在render方法里,現在你可以將它們抽離出來了。順帶可以將生命周期等方法挪出來了,用高階組件lifecycle代替。

const enhance = isLoading => { return compose( lifecycle({ componentDidMount() { setTimeout(() => { this.setState({ name: 阿里雲中台前端 }) }, 1000); } }), branch(isLoading, withLoading) )}

branch接受3個參數,第一個為Function,用來判斷執行哪一個分支,如果結果為true,則執行withLoading高階組件,否則執行第二個高階組件,如果第二個高階組件並未填寫,則默認渲染真實的業務組件。

情景二:維護組件自身的State

我們經常會有Tab切換,點擊展開(收起)等與業務數據無關的狀態需要維護,回想以前的代碼,我們可能會使用setState,有了recompose,我們可以使用withStatewithHandlers來避免手動setState的出現,將展示邏輯和UI進行分離。

const enhance = compose( withState(active, changeActive, false), withHandlers({ toggle: (props) => { return (...args) => { return props.changeActive(active => !active); } } }))

使用了上述2個高階組件後,我們只需要在業務組件中從props獲取toggle方法即可。

情景三:組件嵌套

組件嵌套這種場景我們是最熟悉不過了的,比如經常使用的Modal組件,我們來看一下Modal組件的官方示例代碼。

在實際項目中,我們會有多個地方使用到Modal組件,如果都重複一遍上述代碼,boilerplate代碼將非常多,為此,我們可以將它轉變為一個高階組件,與常規方式不同,我們本次使用recompose提供的HOC來組織我們的代碼。

首先,我們將state和handler抽離出來,單獨作為一個高階組件。

const withModal = compose( withState(visible, setVisible, false), withHandlers({ showModal: (props) => { return () => { props.setVisible(visible => true); } }, handleOk: (props) => { return () => { props.setVisible(visible => false); } }, handleCancel: (props) => { return () => { props.setVisible(visible => false); } }, }));

隨後,我們將ModalView代碼也抽離出來,寫一個functional Components

const MyModal = ({ visible, handleOk, handleCancel, children }) => { return <Modal title="Basic Modal" visible={visible} onOk={handleOk} onCancel={handleCancel} > {children} </Modal>;}

在使用時,我們只需要做如下操作:

const ContentWithModal = nest(MyModal,Content);@withModalclass App {// ...render(){ <ContentWithModal/>;}}

我們使用了nest方法,將Content組件植入到MyModal組件里,相比傳統的高階組件寫法,語義化大幅提高。同時我們也不僅僅局限於使用組件庫提供的Modal組件了,只要我們的自定義組件實現了withModal高階組件對應的Handler即可。

總結

recompose為我們提供了許多便捷的HOC,幫助我們將UI和業務邏輯進行分離,相比我們熟知的組件層的復用,我們又往前進了一步——行為可復用

如果你也有超贊的高階組件用法,歡迎評論,與大家進行分享。??

推薦閱讀:

前端日刊-2018.01.20
我的CSS學習之旅
VuePress 快速踩坑
實現符合 Promise/A+ 規範的Promise
什麼是json jsonp 與ajax關係

TAG:React | 前端開發 | 阿里雲 |