React元件設計模式-Render-props
寫業務時,我們經常需要抽象一些使用頻率較高的邏輯,但是除了高階元件可以抽象邏輯,RenderProps也是一種比較好的方法。
RenderProps,顧名思義就是將元件的props渲染出來。實際上是讓元件的props接收函式,由函式來渲染內容。將通用的邏輯抽象在該元件的內部,然後依據業務邏輯來呼叫函式(props內渲染內容的函式),從而達到重用邏輯的目的。
簡單實現
我們先看一個最簡單的RenderProps模式的實現:
const RenderProps = props => <>
{props.children(props)}
</>
在這裡,RenderProps元件的子元件是一個函式props.children(props),而props.children返回的是UI元素。
使用時的程式碼如下:
<RenderProps>
{() => <>Hello RenderProps</>}
</RenderProps>
以上未作任何的業務邏輯處理,有什麼用處呢?我們可以想到,可以在 RenderProps 元件中去用程式碼操控返回的結果。
以最常見的使用者登入邏輯為例,希望在登陸之後才可以看到內容,否則展示請登入:
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元件的增強功能。
函式名不僅可以是children
平時一般使用的時候,props.children都是具體的元件例項,但上邊的實現是基於以函式為子元件(children(props)),被呼叫返回UI。
同樣,可以呼叫props中的任何函式。還是以上邊的邏輯為例:
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元件內部,通過判斷是否登陸來決定顯示哪個元件。
資源搜尋網站大全 https://www.renrenfan.com.cn 廣州VI設計公司https://www.houdianzi.com
總結
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也提供了一種新模式來解決這個問題。這部分展開來說的話是另一個話題了,我也在摸索中。