寫業務時,咱們常常須要抽象一些使用頻率較高的邏輯,可是除了高階組件能夠抽象邏輯,RenderProps也是一種比較好的方法。react
RenderProps,顧名思義就是將組件的props渲染出來。其實是讓組件的props接收函數,由函數來渲染內容。將通用的邏輯
抽象在該組件的內部,而後依據業務邏輯來調用函數(props內渲染內容的函數),從而達到重用邏輯的目的。函數
咱們先看一個最簡單的RenderProps模式的實現:code
const RenderProps = props => <> {props.children(props)} </>
在這裏,RenderProps組件的子組件是一個函數props.children(props)
,而props.children返回的是UI元素。get
使用時的代碼以下:it
<RenderProps> {() => <>Hello RenderProps</>} </RenderProps>
以上未做任何的業務邏輯處理,有什麼用處呢?咱們能夠想到,能夠在 RenderProps 組件中去用代碼操控返回的結果。
以最多見的用戶登陸邏輯爲例,但願在登錄以後才能夠看到內容,不然展現請登陸:import
const Auth = props => { const userName = getUserName() if (userName) { const allProps = {userName, ...props} return <> {props.children(allProps)} </> } else { return <>請登陸</> } } <Auth> {({userName}) => <>Hello!{userName}</>} </Auth>
props.children(allProps)
就至關於Auth組件嵌套的({userName}) => <>Hello!{userName}</>
登錄
上邊的例子中,用戶若已經登錄,getUserName返回用戶名,不然返回空。這樣咱們就能夠判斷返回哪些內容了。
固然,上邊經過renderProps傳入了userName,這屬於Auth組件的加強功能。渲染
平時通常使用的時候,props.children都是具體的組件實例,但上邊的實現是基於以函數爲子組件(children(props)
),被調用返回UI。
一樣,能夠調用props中的任何函數。仍是以上邊的邏輯爲例:plugin
const Auth = props => { const userName = 'Mike' if (userName) { const allProps = { userName, ...props } return <>{props.login(allProps)}</> } else { return <> {props.noLogin(props)} </> } }
使用方法以下:方法
<Auth login={({userName}) => <h1>Hello {userName}</h1>} noLogin={() => <h1>please login</h1>} />
這裏,Auth組件的props接收兩個函數:login(表示已經登陸),noLogin(表未登陸),
Auth組件內部,經過判斷是否登錄來決定顯示哪一個組件。
render-props做爲一種抽象通用邏輯的方法,其自己也會遇到像高階組件那樣層層嵌套的問題。
<GrandFather> {Props => { <Father> {props => { <Son {...props} />; }} </Father>; }} </GrandFather>
但和高階組件不一樣的是,因爲渲染的是函數(高階組件渲染的是組件),就爲利用compose提供了機會。例如react-powerplugin
。
import { compose } from 'react-powerplug' const ComposeComponent = compose( <GrandFather />, <Father /> ) <ComposeComponent> {props => { <Son {...props} />; }} <ComposeComponent/>
還有Epitath
也提供了一種新模式來解決這個問題。這部分展開來講的話是另外一個話題了,我也在摸索中。