详解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 .tmpl(), .template()学习资料小结
Jul 18 Javascript
JS将所有对象s的属性复制给对象r(原生js+jquery)
Jan 25 Javascript
js判断设备是否为PC并调整图片大小
Feb 12 Javascript
Jquery中CSS选择器用法分析
Feb 10 Javascript
基于 Node.js 实现前后端分离
Apr 23 Javascript
微信小程序 教程之引用
Oct 18 Javascript
jQuery学习笔记——jqGrid的使用记录(实现分页、搜索功能)
Nov 09 Javascript
javascript过滤数组重复元素的实现方法
May 03 Javascript
jQuery实现在HTML文档加载完毕后自动执行某个事件的方法
May 08 jQuery
JavaScript实现元素滚动条到达一定位置循环追加内容
Dec 28 Javascript
Vue底层实现原理总结
Feb 17 Javascript
浅谈Vue.js 关于页面加载完成后执行一个方法的问题
Apr 01 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连接数据库代码应用分析
2011/05/29 PHP
PHP中创建图像并绘制文字的例子
2014/11/19 PHP
CI框架(CodeIgniter)操作redis的方法详解
2018/01/25 PHP
js兼容的placeholder属性详解
2013/08/18 Javascript
js网页实时倒计时精确到秒级
2014/02/10 Javascript
js监控IE火狐浏览器关闭、刷新、回退、前进事件
2014/07/23 Javascript
JavaScript 实现的 zip 压缩和解压缩工具包Zip.js使用详解
2015/12/14 Javascript
JavaScript判断DIV内容是否为空的方法
2016/01/29 Javascript
jquery中关于bind()方法的使用技巧分享
2017/03/30 jQuery
nodejs开发微信小程序实现密码加密
2017/07/11 NodeJs
JQ图片文件上传之前预览功能的简单实例(分享)
2017/11/12 Javascript
AngularJS实现的生成随机数与猜数字大小功能示例
2017/12/25 Javascript
JavaScript使用类似break机制中断forEach循环的方法
2018/11/13 Javascript
vue中利用simplemde实现markdown编辑器(增加图片上传功能)
2019/04/29 Javascript
element-ui上传一张图片后隐藏上传按钮功能
2019/05/22 Javascript
layUI实现前端分页和后端分页
2019/07/27 Javascript
[38:21]2018DOTA2亚洲邀请赛3月30日 小组赛A组 LGD VS Newbee
2018/03/31 DOTA
[01:13:01]2018DOTA2亚洲邀请赛 4.4 淘汰赛 TNC vs VG 第三场
2018/04/05 DOTA
使用requests库制作Python爬虫
2018/03/25 Python
pandas apply 函数 实现多进程的示例讲解
2018/04/20 Python
tensorflow saver 保存和恢复指定 tensor的实例讲解
2018/07/26 Python
Python3实现获取图片文字里中文的方法分析
2018/12/13 Python
linux环境下安装python虚拟环境及注意事项
2020/01/07 Python
Python基础之列表常见操作经典实例详解
2020/02/26 Python
python 深度学习中的4种激活函数
2020/09/18 Python
python 读取yaml文件的两种方法(在unittest中使用)
2020/12/01 Python
python 使用cycle构造无限循环迭代器
2020/12/02 Python
世界上最大的餐具公司:Oneida
2016/12/17 全球购物
美国最大的骑马用品零售商:HorseLoverZ
2017/01/12 全球购物
成品库仓管员岗位职责
2014/04/06 职场文书
冬季施工防火方案
2014/05/17 职场文书
文明好少年事迹材料
2014/08/19 职场文书
拿破仑传读书笔记
2015/07/01 职场文书
2015少先队大队辅导员工作总结
2015/07/24 职场文书
交通事故协议书范本
2016/03/19 职场文书
mongodb的安装和开机自启动详细讲解
2021/08/02 MongoDB