详解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 相关文章推荐
Jquery 学习笔记(一)
Oct 13 Javascript
Js 时间函数getYear()的使用问题探讨
Apr 01 Javascript
jQuery插件实现表格隔行换色且感应鼠标高亮行变色
Sep 22 Javascript
jquery validation验证身份证号,护照,电话号码,email(实例代码)
Nov 06 Javascript
js中通过getElementsByName访问name集合对象的方法
Oct 31 Javascript
微信小程序 radio单选框组件详解及实例代码
Jan 10 Javascript
解决BootStrap Fileinput手机图片上传显示旋转问题
Jun 01 Javascript
React-native桥接Android原生开发详解
Jan 17 Javascript
详解React之key的使用和实践
Sep 29 Javascript
vue计算属性get和set用法示例
Feb 08 Javascript
mpvue微信小程序的接口请求fly全局拦截代码实例
Nov 13 Javascript
Vue中常用rules校验规则(实例代码)
Nov 14 Javascript
详解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 魔术函数使用说明
2010/02/21 PHP
php通过文件头检测文件类型通用代码类(zip,rar等)
2010/10/19 PHP
codeigniter显示所有脚本执行时间的方法
2015/03/21 PHP
PHP输出一个等腰三角形的方法
2015/05/12 PHP
PHP和MYSQL实现分页导航思路详解
2017/04/11 PHP
PHP如何通过date() 函数格式化显示时间
2020/11/13 PHP
jQuery源码分析-05异步队列 Deferred 使用介绍
2011/11/14 Javascript
js验证输入是否为手机号码或电话号码示例
2013/12/30 Javascript
javascript创建和存储cookie示例
2014/01/07 Javascript
JavaScript在Android的WebView中parseInt函数转换不正确问题解决方法
2015/04/25 Javascript
js中 javascript:void(0) 用法详解
2015/08/11 Javascript
Bootstrap安装环境配置教程分享
2016/05/27 Javascript
easy ui datagrid 从编辑框中获取值的方法
2017/02/22 Javascript
AngularJS使用ng-repeat遍历二维数组元素的方法详解
2017/11/11 Javascript
vue移动UI框架滑动加载数据的方法
2018/03/12 Javascript
Bootstrap开发中Tab标签页切换图表显示问题的解决方法
2018/07/13 Javascript
详解Vue基于vue-quill-editor富文本编辑器使用心得
2019/01/03 Javascript
移动端 Vue+Vant 的Uploader 实现上传、压缩、旋转图片功能
2019/06/10 Javascript
javascript sort()对数组中的元素进行排序详解
2019/10/13 Javascript
Vue + element 实现多选框组并保存已选id集合的示例代码
2020/06/03 Javascript
[04:44]DOTA2英雄梦之声_第12期_矮人直升机
2014/06/21 DOTA
python通过urllib2获取带有中文参数url内容的方法
2015/03/13 Python
Django 跨域请求处理的示例代码
2018/05/02 Python
Python日期时间对象转换为字符串的实例
2018/06/22 Python
python实现的汉诺塔算法示例
2019/10/23 Python
kafka-python 获取topic lag值方式
2019/12/23 Python
Python使用re模块验证危险字符
2020/05/21 Python
完美解决keras保存好的model不能成功加载问题
2020/06/11 Python
解决keras backend 越跑越慢问题
2020/06/18 Python
Java程序员面试题
2013/07/15 面试题
大学生职业生涯规划范文——找准自我,定位人生
2014/01/23 职场文书
高中军训感言500字
2014/02/24 职场文书
初中生旷课检讨书范文
2014/10/06 职场文书
承诺书应该怎么写?
2019/09/10 职场文书
Mysql数据库group by原理详解
2022/07/07 MySQL
使用HBuilder制作一个简单的HTML5网页
2022/07/07 HTML / CSS