详解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 相关文章推荐
javascript instanceof 与typeof使用说明
Jan 11 Javascript
JavaScript判断变量是否为undefined的两种写法区别
Dec 04 Javascript
js取模(求余数)隔行变色
May 15 Javascript
javascript 数组操作详解
Jan 29 Javascript
JS动态给对象添加事件的简单方法
Jul 19 Javascript
javascript使用 concat 方法对数组进行合并的方法
Sep 08 Javascript
vue使用element-ui的el-input监听不了回车事件的解决方法
Jan 12 Javascript
vue-router3.0版本中 router.push 不能刷新页面的问题
May 10 Javascript
JavaScript&quot;模拟事件&quot;的注意要点详解
Feb 13 Javascript
JavaScript实现预览本地上传图片功能完整示例
Mar 08 Javascript
Node配合WebSocket做多文件下载以及进度回传
Nov 07 Javascript
详解Vue3使用axios的配置教程
Apr 29 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 socket(fsockopen)的应用实例分析
2013/06/02 PHP
php preg_replace替换实例讲解
2013/11/04 PHP
PHP两种去掉数组重复值的方法比较
2014/06/19 PHP
详解 PHP加密解密字符串函数附源码下载
2015/12/18 PHP
深入理解JavaScript编程中的同步与异步机制
2015/06/24 Javascript
jQuery点击其他地方时菜单消失的实现方法
2016/04/22 Javascript
微信小程序开发经验总结(推荐)
2017/01/11 Javascript
ES6新特性之函数的扩展实例详解
2017/04/01 Javascript
微信小程序 空白页重定向解决办法
2017/06/27 Javascript
js 两个日期比较相差多少天的实例
2017/10/19 Javascript
bootstrap动态调用select下拉框的实例代码
2018/08/09 Javascript
解决JQuery的ajax函数执行失败alert函数弹框一闪而过问题
2019/04/10 jQuery
js 下拉菜单点击旁边收起实现(踩坑记)
2019/09/29 Javascript
javascript实现前端分页功能
2020/11/26 Javascript
[38:30]2014 DOTA2国际邀请赛中国区预选赛 LGD-GAMING VS CIS 第一场2
2014/05/24 DOTA
[05:59]2018DOTA2国际邀请赛寻真——只为胜利的Secret
2018/08/13 DOTA
[52:06]完美世界DOTA2联赛决赛日 Inki vs LBZS 第一场 11.08
2020/11/10 DOTA
[32:07]完美世界DOTA2联赛PWL S3 LBZS vs Rebirth 第一场 12.16
2020/12/17 DOTA
django使用图片延时加载引起后台404错误
2017/04/18 Python
PyQt5每天必学之事件与信号
2018/04/20 Python
Python基于生成器迭代实现的八皇后问题示例
2018/05/23 Python
python实现定时压缩指定文件夹发送邮件
2020/12/22 Python
如何基于线程池提升request模块效率
2020/04/18 Python
python中wheel的用法整理
2020/06/15 Python
css3 column实现卡片瀑布流布局的示例代码
2018/06/22 HTML / CSS
CSS3实现苹果手机解锁的字体闪亮效果示例
2021/01/05 HTML / CSS
基于HTML5的WebSocket的实例代码
2018/08/15 HTML / CSS
泰坦健身器材:Titan Fitness
2018/02/13 全球购物
Linux文件系统类型
2012/02/15 面试题
英文自我鉴定
2013/12/10 职场文书
迎八一活动主题
2014/01/31 职场文书
新党章的学习心得体会
2014/11/07 职场文书
2014年房产销售工作总结
2014/12/08 职场文书
运动会班级口号霸气押韵
2015/12/24 职场文书
golang为什么要统一错误处理
2022/04/03 Golang
MySQL索引失效十种场景与优化方案
2023/05/08 MySQL