Open hjzheng opened 7 years ago
在书写 JSX 时,经常会有一类需求,就是在特定条件下 render 一些组件。 例如:
{this.showMessage && <Message type={'warning'} />}
{this.loading ? <Loading /> : <Table />}
这里,我使用 JavaScript 表达式进行处理,这样做,从代码的可读性和可维护性上看起来都还不错。
继续增加复杂度
{ show && (isAdmin || hasPermission) && <Dialog /> }
{ isShow && configDataIsDone && (isAdmin || hasPermission) && <Dialog /> }
显而易见,随着复杂度的增加,代码的可读性变的很差,可维护性也变的不好。
此时,最简单的处理方式,创建一个 helper 函数
canShowDialog () { const { isShow, configDataIsDone, isAdmin, hasPermission } = this.props; return isShow && configDataIsDone && (isAdmin || hasPermission); } ... ... { this.canShowDialog() && <Dialog /> }
或者创建一个 getter
get canShowDialog () { const { isShow, configDataIsDone, isAdmin, hasPermission } = this.props; return isShow && configDataIsDone && (isAdmin || hasPermission); } ... ... { this.canShowDialog && <Dialog /> }
当然,有些时候,也可以依赖一些第三方库 例如 render-if
const { isShow, configDataIsDone, isAdmin, hasPermission } = this.props; const canShowDialog = renderIf(isShow && configDataIsDone && (isAdmin || hasPermission)); ... ... { this.canShowDialog(<Dialog />) }
还可以使用高阶组件 react-only-if
const { isShow, configDataIsDone, isAdmin, hasPermission } = this.props; const DialogOnlyIf = onlyIf(({isShow, configDataIsDone, isAdmin, hasPermission}) => { return isShow && configDataIsDone && (isAdmin || hasPermission); })(<Dialog />); ... ... { <DialogOnlyIf isShow={...} configDataIsDone={...} isAdmin={...} hasPermission={...} /> }
即使这样,可读性上还是稍差点,不可否认通用编程语言在功能上,远大于模板,毕竟模板只是 DSL,针对特定领域的语言,在某些点上的能力毕竟有限,因为它是针对特定领域的,所以在特定领域的可读性和易用上要好于通用编程语言。
想象一下, 我们可不可以增加一些条件组件,参考一下 AngularJS1.x:
例如:
<div ng-if=“true”>要显示内容</div>
将组件设计成这样:
<If condition={isShow && configDataIsDone && (isAdmin || hasPermission)}> <Dialog /> </If>
其他组件 参考 ng-switch (else 和 else If 可以用 switch 代替)
<If condition={...}> {'if语句'} </If> <Switch> <When condition={...}>...</When> <When condition={...}>...</When> <Default>....</Default> </Switch>
庆幸的是,有第三方的库可以进行支持,目前我所知道的有两个库: react-if jsx-control-statements
以 jsx-control-statements 为例:
{/* if语句 */} <If condition={ test }> <span>Truth</span> </If> {/* switch 语句 */} <Choose> <When condition={ test1 }> <span>IfBlock</span> </When> <When condition={ test2 }> <span>ElseIfBlock</span> <span>Another ElseIfBlock</span> <span>...</span> </When> <Otherwise> <span>ElseBlock</span> </Otherwise> </Choose> {/* for 循环 */} <For each="item" index="idx" of={ [1,2,3] }> <span key={ idx }>{ item }</span> <span key={ idx + '_2' }>Static Text</span> </For>
先赞一个,想法非常好👍 不过 jsx 的拥趸们估计要坐不住了: 『什么竟然说 JSX 不如模板语法?!!』 『你这跟写模板有什么区别,JSX 才是正道,你这个异教徒!』 『这么写简直是在开倒车!!』 哈哈哈哈(逃
在书写 JSX 时,经常会有一类需求,就是在特定条件下 render 一些组件。 例如:
这里,我使用 JavaScript 表达式进行处理,这样做,从代码的可读性和可维护性上看起来都还不错。
继续增加复杂度
继续增加复杂度
显而易见,随着复杂度的增加,代码的可读性变的很差,可维护性也变的不好。
此时,最简单的处理方式,创建一个 helper 函数
或者创建一个 getter
当然,有些时候,也可以依赖一些第三方库 例如 render-if
还可以使用高阶组件 react-only-if
即使这样,可读性上还是稍差点,不可否认通用编程语言在功能上,远大于模板,毕竟模板只是 DSL,针对特定领域的语言,在某些点上的能力毕竟有限,因为它是针对特定领域的,所以在特定领域的可读性和易用上要好于通用编程语言。
想象一下, 我们可不可以增加一些条件组件,参考一下 AngularJS1.x:
例如:
将组件设计成这样:
其他组件 参考 ng-switch (else 和 else If 可以用 switch 代替)
庆幸的是,有第三方的库可以进行支持,目前我所知道的有两个库: react-if jsx-control-statements
以 jsx-control-statements 为例: