使用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,我們可以使用withState
和withHandlers
來避免手動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); } }, }));
隨後,我們將Modal
的View
代碼也抽離出來,寫一個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關係