详解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 Chart 插件整理
Jun 18 Javascript
基于jquery的当鼠标滚轮到最底端继续加载新数据思路分享(多用于微博、空间、论坛 )
Oct 10 Javascript
jQuery通过写入cookie实现更换网页背景的方法
Apr 15 Javascript
JS控制弹出悬浮窗口(一览画面)的实例代码
May 30 Javascript
Web程序员必备的7个JavaScript函数
Jun 14 Javascript
使用contextMenu插件实现Bootstrap table弹出右键菜单
Feb 20 Javascript
微信小程序 实现动态显示和隐藏某个控件
Apr 27 Javascript
Vue.js学习笔记之修饰符详解
Jul 25 Javascript
angularJs在多个控制器中共享服务数据的方法
Sep 30 Javascript
js中的reduce()函数讲解
Jan 18 Javascript
JS+canvas画布实现炫酷的旋转星空效果示例
Feb 13 Javascript
vue中使用vue-pdf的方法详解
Sep 05 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
第十三节 对象串行化 [13]
2006/10/09 PHP
php日期转时间戳,指定日期转换成时间戳
2012/07/17 PHP
thinkPHP线上自动加载异常与修复方法实例分析
2016/12/01 PHP
PHP数据库操作二:memcache用法分析
2017/08/16 PHP
php+ajax 文件上传代码实例
2019/03/18 PHP
Javascript调用XML制作连动下拉列表框
2006/06/25 Javascript
基于jquery的关于动态创建DOM元素的问题
2010/12/24 Javascript
基于jquery的设置页面文本框 只能输入数字的实现代码
2011/04/19 Javascript
javascript中常用编程知识
2013/04/08 Javascript
禁用键盘上的(全局)指定键兼容iE、Chrome、火狐
2013/05/14 Javascript
node.js中的http.request.end方法使用说明
2014/12/10 Javascript
jQuery插件实现文件上传功能(支持拖拽)
2020/08/27 Javascript
JQ选择器_选择同类元素的第N个子元素的实现方法
2016/09/08 Javascript
详解jQuery停止动画——stop()方法的使用
2016/12/14 Javascript
vue2.0s中eventBus实现兄弟组件通信的示例代码
2017/10/25 Javascript
js实现左右两侧浮动广告
2018/07/09 Javascript
迅速了解一下ES10中Object.fromEntries的用法使用
2019/03/05 Javascript
js中比较两个对象是否相同的方法示例
2019/09/02 Javascript
使用python检测主机存活端口及检查存活主机
2015/10/12 Python
python使用matplotlib绘制柱状图教程
2017/02/08 Python
对python多线程与global变量详解
2018/11/09 Python
Python selenium根据class定位页面元素的方法
2019/02/26 Python
Python这样操作能存储100多万行的xlsx文件
2019/04/16 Python
关于Python中的向量相加和numpy中的向量相加效率对比
2019/08/26 Python
Django1.11配合uni-app发起微信支付的实现
2019/10/12 Python
pycharm-professional-2020.1下载与激活的教程
2020/09/21 Python
Selenium环境变量配置(火狐浏览器)及验证实现
2020/12/07 Python
css3新增颜色表示方式分享
2014/04/15 HTML / CSS
Sofft鞋官网:世界知名鞋类品牌
2017/03/28 全球购物
雅诗兰黛旗下专业男士保养领导品牌:Lab Series
2017/05/15 全球购物
几道数据库的概念性面试题
2014/05/30 面试题
计算机专业毕业生自荐信范文
2014/03/06 职场文书
2016形势与政策学习心得体会
2016/01/12 职场文书
2019年大学生职业生涯规划书
2019/03/25 职场文书
vue使用v-model进行跨组件绑定的基本实现方法
2021/04/28 Vue.js
Python 读写 Matlab Mat 格式数据的操作
2021/05/19 Python