详解React 的几种条件渲染以及选择


Posted in Javascript onOctober 23, 2018

对于一个展示页面来讲, 通常有好几种展示状态(以列表页为例):

  • 数据为空, 空页面
  • 取数据时发生错误, 错误页面
  • 数据正常
  • 加载状态

针对以上三种情况, react渲染列表的时候要正确判断并渲染出相应的视图, 也就是条件渲染. 不同于vue的v-if, v-show等框架提供的api, react的条件渲染都是js原生的再加上一点点的hack. 比如react文档提到的. if/else, && 和三目等等.

当然上面的都是常用的一些方法, 但是也存在着各种问题, 比如条件分支过多的的事时候代码也会越来越乱. 下面提供几种具有普适性的方法

if/else, 三目以及 短路运算符

这三个方法都是官方文档提到的, 这里就放到一起了, 其实这三种方案都是类似的: 在render生命周期里做相应的判断. 不过三目和短路运算符可以在jsx行内使用.

if/else

class List extends Component {
 static propTypes = {
  status: PropTypes.oneOf(['loading', 'error', 'success', 'empty'])
 }
 
 render () {
  const { status } = this.props
  if (status === 'loading') {
   return <div>
    加载状态
   </div>
  } 
  
  if (status === 'error') {
   return <div>
    错误状态
   </div>
  }


  if (status === 'success') {
   return <div>
    成功状态
   </div>
  }

  if (status === 'empty') {
   return <div>
    空状态
   </div>
  }
 }
}

可以看到这种写法胜在清楚明了, 但是如果判断分支越来越多代码无可避免的会非常冗余, 同时复用性也堪忧.

Render(IF)组件

这里的render当然不是生命周期里的render, 我们可以跟vue里的v-if对应起来

function Render ({ if: cond, children }) {
  return cond ? children : null
}

上面是简单的Render组件, 使用起来是这样的

class List extends Component {
  static propTypes = {
    status: PropTypes.oneOf(['loading', 'error', 'success', 'empty'])
  }
  
 render () {
  const { status } = this.props
  return (
   <div>
    <Render if={status === 'loading'} >
     加载状态
    </Render>

    <Render if={status === 'error'} >
     错误状态
    </Render>

    <Render if={status === 'success'} >
     成功状态
    </Render>

    <Render if={status === 'empty'} >
     空状态
    </Render>
   </div>
  )
  }
}

相比使用在render里使用大量的if/else 上面的写法无疑更加清楚明了了. 如果所有列表业务组件统一起来, 状态保持一致, 我们可以做更高层次的抽象, 把其他状态都抽象到一个高阶函数之中, 我们写代码的时候只要确保success的状态能正确渲染即可

立即执行函数

jsx里是可以写变量, 同时立即执行函数也是可以的

class List extends Component {
 static propTypes = {
   status: PropTypes.oneOf(['loading', 'error', 'success', 'empty'])
 }
 
 render () {
  const { status } = this.props
  return (
   <div>
    {(() => {
     switch (status) {
      case 'loading':
       return <div>加载状态</div>
      
      case 'error':
       return <div>错误状态</div>
      
      case 'success':
       return <div>成功状态</div>
      
      case 'empty':
       return <div>空状态</div>
     }
    })()}
   </div>
  )
 }
}

立即函数的复用显然不太现实, 所以立即函数的适用场景是那种相对比较复杂但无法复用的组件

高阶组件

对于高阶组件的概念就不做赘述了, 我们把条件渲染的逻辑放到高阶组件中, 除了逻辑的抽象外, 也可以提高组件的复用率.

const withList = WrappedComponent => {
 return class PP extends Component {
  render() {
   const { status } = this.props
   switch (status) {
    case 'loading':
     return <div>加载状态</div>
    
    case 'error':
     return <div>错误状态</div>
    
    case 'success':
     return <WrappedComponent {...this.props}/>
    
    case 'empty':
     return <div>空状态</div>
   }
  }
 }
}

如果我们可以保证所有列表的props一致(也就是都使用status判断状态), 我们完全可以专注的写status为success的状态:

@withList
class List extends Component {
 static propTypes = {
  status: PropTypes.oneOf(['loading', 'error', 'success', 'empty'])
 }
 
 render () {
  return (
   <div>
    成功页面
   </div>
  )
 }
}

其次我们可以把加载, 错误, 以及空状态统一抽成组件, 对于提高组件的复用率无疑可以起很大作用.

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
代码精简的可以实现元素圆角的js函数
Jul 21 Javascript
jquery $(document).ready() 与window.onload的区别
Dec 28 Javascript
js中if语句的几种优化代码写法
Mar 12 Javascript
JS 自定义带默认值的函数
Jul 21 Javascript
js中事件的处理与浏览器对象示例介绍
Nov 29 Javascript
js星星评分效果
Jul 24 Javascript
jQuery给动态添加的元素绑定事件的方法
Mar 09 Javascript
BootStrap表单宽度设置方法
Mar 10 Javascript
vuex actions传递多参数的处理方法
Sep 18 Javascript
js canvas实现二维码和图片合成的海报
Nov 19 Javascript
了解JavaScript中的选择器
May 24 Javascript
如何正确解决VuePress本地访问出现资源报错404的问题
Dec 03 Vue.js
详解create-react-app 2.0版本如何启用装饰器语法
Oct 23 #Javascript
彻底弄懂 JavaScript 执行机制
Oct 23 #Javascript
深入理解JavaScript 中的执行上下文和执行栈
Oct 23 #Javascript
浅谈JavaScript 代码整洁之道
Oct 23 #Javascript
使用jquery Ajax实现上传附件功能
Oct 23 #jQuery
详解如何构建Promise队列实现异步函数顺序执行
Oct 23 #Javascript
jquery实现动态添加附件功能
Oct 23 #jQuery
You might like
php中目录,文件操作详谈
2007/03/19 PHP
解析PHP中empty is_null和isset的测试
2013/06/29 PHP
Yii分页用法实例详解
2014/12/04 PHP
php按单词截取字符串的方法
2015/04/07 PHP
php实现的日历程序
2015/06/18 PHP
PHP常用设计模式之委托设计模式
2016/02/13 PHP
YII框架中使用memcache的方法详解
2017/08/02 PHP
PHP实现的用户注册表单验证功能简单示例
2019/02/25 PHP
使用Laravel中的查询构造器实现增删改查功能
2019/09/03 PHP
javascript英文日期(有时间)选择器
2007/05/02 Javascript
用cookies实现的可记忆的样式切换效果代码下载
2007/12/24 Javascript
js实现弹窗插件功能实例代码分享
2013/12/12 Javascript
JS函数重载的解决方案
2014/05/13 Javascript
JavaScript对象反射用法实例
2015/04/17 Javascript
JavaScript检测原始值、引用值、属性
2016/06/20 Javascript
AngularJS 实现弹性盒子布局的方法
2016/08/30 Javascript
使用Angular.js实现简单的购物车功能
2016/11/21 Javascript
angular1配合gulp和bower的使用教程
2018/01/19 Javascript
node打造微信个人号机器人的方法示例
2018/04/26 Javascript
脚手架vue-cli工程webpack的作用和特点
2018/09/29 Javascript
Vue利用History记录上一页面的数据方法实例
2018/11/02 Javascript
基于Vue插入视频的2种方法小结
2019/04/02 Javascript
vue el-table实现自定义表头
2019/12/11 Javascript
win7安装python生成随机数代码分享
2013/12/27 Python
python3读取MySQL-Front的MYSQL密码
2017/05/03 Python
python读取目录下所有的jpg文件,并显示第一张图片的示例
2019/06/13 Python
Django应用程序入口WSGIHandler源码解析
2019/08/05 Python
通过Python pyecharts输出保存图片代码实例
2020/11/25 Python
利用Python批量识别电子账单数据的方法
2021/02/08 Python
日本最新流行服饰网购:Nissen
2016/07/24 全球购物
美味咖啡的顶级烘焙师:Cafe Britt
2018/03/15 全球购物
Android面试题附答案
2014/12/08 面试题
平安工地建设方案
2014/05/06 职场文书
2014年党员学习“三严三实”思想汇报
2014/09/15 职场文书
银行优秀员工推荐信
2015/03/24 职场文书
Python OpenCV实现图形检测示例详解
2022/04/08 Python