2017-03-16 17 views
3

我正在重構無狀態的功能組件使用branchrenderComponentrecompose使用分支從重組

原來的組件看起來是這樣的:

const Icon = props => { 
    const { type, name } = props 
    let res 
    if (type === 'font') { 
    return (<FontIcon name={name} />) 
    } else if (type === 'svg') { 
    res = (<SvgIcon glyph={name} />) 
    } 

    return res 
} 

與分支組件看起來是這樣的:

const isFont = props => { 
    const { type } = props 
    return type === 'font' 
} 

const FontIconHoC = renderComponent(FontIcon) 
const SvgIconHoC = renderComponent(SvgIcon) 

const Icon = branch(isFont, FontIconHoC, SvgIconHoC) 

Icon.propTypes = { 
    type: string, 
    name: string 
} 

export default Icon 

我嘗試呈現組件使用:

<Icon name='crosshairs' type='font' /> 

產生的錯誤看起來像這樣:

invariant.js:44Uncaught Error: Icon(...): A valid React element (or null) must be returned. You may have returned undefined, an array or some other invalid object. 

回答

6

branch返回一個HOC,它接受一個組件並返回一個組件,因此branch(...)是一個HOC,branch(...)(...)是一個組件。

就你而言,因爲Icon不是一個組件,而是一個HOC,所以React無法渲染它。爲了解決這個問題,你可以移動SvgIcon出從branch的論點,並適用於branch(...)返回的HOC,例如:

const Icon = branch(
    isFont, 
    FontIconHoC, 
    a => a 
)(SvgIcon) 

我們使用了一種身份的函數(a => a)至branch第三個參數。你可以認爲身份函數也是一個HOC,它基本上只是返回它所得到的組件,什麼也不做。

由於這種模式經常使用,所以第三個參數branch默認爲身份函數。因此,我們可以省略它並簡化代碼:

const Icon = branch(
    isFont, 
    FontIconHoC 
)(SvgIcon) 

我已經爲這些代碼創建了一個jsfiddle。你可以試試here

-1

您也可以使用if語句而不是分支。考慮你在做if語句時遇到了一些困難。

也許有時間重新考慮那個圖書館?

+1

問題的目標是弄清楚如何使用文檔中的分支。這是我爲自己做的探索性工作。雖然我同意分支的使用可能有限,但有一些來自'recompose'的實用程序,比如'withHandlers'和'withReducer',我真的很興奮。當將巨大的React組件重構爲更小的無狀態組件時,它確實幫助了我。 – vamsiampolu

+0

我鼓勵你考慮使用模式重組鼓勵,而不必使用庫本身 –

+0

@BradfordMedeiros這是一個可怕的答案。在圖書館遇到困難並不意味着你應該重新考慮圖書館。重構的目的是使代碼更具可讀性和可測性。 –