通過組件模擬條件分支
例子
<Branch> // 分支容器
<If status={false}> // if
if
</If>
<ElseIf status={false}> // else if
else
</ElseIf>
<br />
// 支持嵌套
<Else> // else
<Branch>
<If status={false}>
next level if
</If>
<ElseIf status={true}>
next level else-if
</ElseIf>
</Branch>
</Else>
end // 組件之間的任意位置可插入其他內(nèi)容, 都將被渲染
</Branch>
基礎(chǔ)組件
-
<Branch>
判斷容器: 當(dāng)存在多條件判斷時浅浮,判斷組件需要包裹在該組件下 -
<If>
if 判讀, 單條If組件可不使用 Branch 包裹 -
<ElseIf>
else if 判斷 -
<Else>
else 判斷
組件用例
獨立使用If
<If status={status}>
....
</If>
<If status={status}>
....
</If>
if else
<Branch>
<If status={status}>
...
</If>
<Else>
...
</Else>
</Branch
if else-if
<Branch>
<If status={status01}>
...
</If>
<ElseIf status={status02}>
...
</ElseIf>
</Branch
if else-if else
<Branch>
<If status={status01}>
...
</If>
<ElseIf status={status02}>
...
</ElseIf>
<Else>
...
</Else>
</Branch
組件實現(xiàn)
If
export const If = props => {
const {
children,
status
} = props
return (
<>
{ status ? children : null }
</>
)
}
ElseIf
export const ElseIf = props => {
return (
<>
{ props.status ? props.children : null }
</>
)
}
Else
export const Else = props => {
return (
<>
{ props.children }
</>
)
}
Branch
export const Branch = props => {
// 通過函數(shù)name屬性判斷組件類型
const types = [
// Branch.name,
If.name,
ElseIf.name,
Else.name
]
const _c = []
const bingo = 'BINGO'
let currentType
/**
* 遍歷子元素沫浆,根據(jù)組件分類判斷是否加入渲染隊列中
*/
React.Children.forEach(props.children, (item) => {
const itemType = item.type ? item.type.name : null
const tactics = [
// 非分支組件或元素
[
() => !itemType || !types.includes(itemType),
() => { _c.push(item) }
],
// 分支組件狀態(tài)為true時,后續(xù)分支組件不再追加
[
() => currentType === bingo,
() => {}
],
[
// if 判斷
() => itemType === If.name && !currentType,
() => {
if(item.props.status){
currentType = bingo
_c.push(item)
}else{
currentType = itemType
}
}
],
[
// else if 判斷
() => itemType === ElseIf.name && currentType === If.name,
() => {
if(item.props.status){
currentType = bingo
_c.push(item)
}else{
currentType = itemType
}
}
],
[
// else 判斷
() => itemType === Else.name && (currentType === If.name || currentType === ElseIf.name),
() => {
currentType = bingo
_c.push(item)
}
]
]
const _b = tactics.find(([check]) => check())
if(_b){
_b[1]()
}else{
throw new Error(`分支組件類型錯誤 ${item.type}: ${item}`)
}
})
return (
<>
{ _c}
</>
)
}