在 Workpop 公司,咱們不斷使用不一樣的組件設計模式來迭代咱們的產品,以適應瞬息萬變的 React 生態系統。早些時候,咱們從試用高階組件設計模式(HOC)中嚐到一點甜頭。前端
高階組件只是一個函數,只不過它返回的是用來渲染 React 組件的函數。android
這裏有個例子:ios
import { Component } from 'React'; export function enhancer() { return (BaseComponent) => { return class extends Component { constructor() { this.state = { visible: false }; } componentDidMount() { this.setState({ visible: true }); } render() { return <BaseComponent {...this.props} {...this.state} />; } } }; }
正如你看到的這個例子,咱們只有一個給你的組件提供功能的函數。在本例中,咱們添加了一些 state
來控制可見性。git
咱們能夠看看它的使用方式:github
// 展現型組件 function Sample({ visible }) { return visible ? <div> I am Visible </div> : <div> I am not Visible </div> } export default enhance()(Sample);
當構建組件時,我強烈建議將展現型組件和加強型組件(高階組件)進行分離。我喜歡使用術語加強型組件來描述高階組件,是由於這個詞從字面上可讓咱們更好的理解它的用途。後端
加強型組件的用途:設計模式
state
,這意味着你再也不須要依賴 Redux 來託管全部 state
(若是你正這樣作);props
(map,reduce 等任何你喜歡的方法)。若是你想用 ES6 的類語法來實現也能夠。我我的傾向於使用函數式無狀態的組件來構建應用的 UI。模塊化
function HellWorld({ message = 'Hello World' }) { return <h1>{message}</h1>; }
使用函數式組件的優勢:函數
而後咱們開始在生產環境中深度使用高階組件了,並在使用過程當中遇到了幾個問題。好比爲簡單的場景不斷地編寫簡單地高階組件就很無聊,沒有將多個高階組件進行合成的方法,也沒法避免開發出冗餘的高階組件(這個最麻煩,但我清楚這有時確實會發生)。人們逐漸陷入高階組件的語法和觀念中步履維艱(正如如今不少工程師的狀態),這種模式彷佛也已漸漸失去了價值。工具
咱們真正須要的解決方案是這樣的:
這就是咱們爲什麼引入 Recompose。
Recompose 是一個爲函數式組件和高階組件開發的 React 工具庫。能夠把它當作 React 的 Lodash。
這正是咱們所須要的。咱們的同事們都喜歡用 Lodash,如今跟他們說開發高階組件將和使用 Lodash 有類似的開發體驗。恩,有戲。
咱們來寫個簡單地 DEMO 看看:
假如咱們有這樣一個組件約束:
state
來控制可見性;export default function Presentation({ title, message, toggleVisibility, isVisible }) { return ( <div> <h1>{title}</h1> {isVisible ? <p>I'm visible</p> : <p> Not Visible </p>} <p>{message}</p> <button onClick={toggleVisibility}> Click me! </button> </div> ); }
如今咱們須要去提取這個組件的加強型組件了。
我一般會把一些 Recompose 的加強型組件合成在一塊兒,因此這個步驟是創建你的 compose:
import { compose } from 'recompose'; export default compose( /*********************************** * * 咱們將把加強型組件放在這裏 * ***********************************/ )(Presentation);
什麼是 Recompose 中的 compose?它至關於 Lodash
中的 flowRight
函數。
咱們可使用 compose 來將多個高階組件轉化爲一個高階組件。
state
好了,咱們如今須要從這個組件中正確獲取 state
。
在 Recompose 中,咱們可使用 withState
加強型組件來設置組件內的 state
,而且使用 withHandlers
加強型組件來設置組件的事件處理函數。
import { compose, withState, withHandlers } from 'recompose'; export default compose( withState('isVisible', 'toggleVis', false), withHandlers({ toggleVisibility: ({ toggleVis, isVisible }) => { return (event) => { return toggleVis(!isVisible); }; }, }) )(Presentation);
這裏咱們設置了一個 isVisible
的 state
,一個控制可見性的方法 toggleVis
,和一個初始值 false。
withHandlers
建立了一個高階組件,它接受一系列 props
並返回一個處理函數,在這個例子中是切換可見性 state
的函數。toggleVisibility
這個函數將做爲 Presentation
組件的一個 prop
。
最後的要作的是給咱們的組件附加一些 props
。
import { compose, withState, withHandlers, withProps } from 'recompose'; export default compose( withState('isVisible', 'toggleVis', false), withHandlers({ toggleVisibility: ({ toggleVis, isVisible }) => { return (event) => { return toggleVis(!isVisible); }; }, }), withProps(({ isVisible }) => { return { title: isVisible ? 'This is the visible title' : 'This is the default title', message: isVisible ? 'Hello I am Visible' : 'I am not visible yet, click the button!', }; }) )(Presentation);
這個模式最酷的地方在於咱們如今就能夠操做組件的 props
了,在這裏,經過操做控制可見性的 state
,咱們能夠展現不一樣的 title 和 message。依我看,這個加強型組件遠比原來全寫在 render 函數中的方式簡潔。
如今你看到了,咱們有了一個可複用的高階組件,它能夠被用在其餘的展現性組件上。同時能夠看到咱們移除了原來高階組件寫法中的不少樣板語法。
在 Recompose 中還有不少有用的 API,瞭解更多!它真的很是像 Lodash
,如今就打開文檔開始寫代碼吧!
若是發現譯文存在錯誤或其餘須要改進的地方,歡迎到 掘金翻譯計劃 對譯文進行修改並 PR,也可得到相應獎勵積分。文章開頭的 本文永久連接 即爲本文在 GitHub 上的 MarkDown 連接。
掘金翻譯計劃 是一個翻譯優質互聯網技術文章的社區,文章來源爲 掘金 上的英文分享文章。內容覆蓋 Android、 iOS、 前端、 後端、 區塊鏈、 產品、 設計、 人工智能等領域,想要查看更多優質譯文請持續關注 掘金翻譯計劃、 官方微博、 知乎專欄。