详解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 相关文章推荐
Dom在ajax技术中的作用说明
Oct 25 Javascript
JS截取url中问号后面参数的值信息
Apr 29 Javascript
原生Ajax 和jQuery Ajax的区别示例分析
Dec 17 Javascript
JavaScript学习笔记之取数组中最大值和最小值
Mar 23 Javascript
自动化测试读写64位操作系统的注册表
Aug 15 Javascript
JavaScript DOM节点操作方法总结
Aug 23 Javascript
浅谈Vue的基本应用
Dec 27 Javascript
bootstrap jquery dataTable 异步ajax刷新表格数据的实现方法
Feb 10 Javascript
Javascript中字符串相关常用的使用方法总结
Mar 13 Javascript
详解动画插件wow.js的使用方法
Sep 13 Javascript
bootstrap实现二级下拉菜单效果
Nov 23 Javascript
vue3自定义dialog、modal组件的方法
Jan 04 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冒泡排序算法的深入理解
2013/06/09 PHP
php中时间函数date及常用的时间计算
2017/05/12 PHP
PHP receiveMail实现收邮件功能
2018/04/25 PHP
使用Zookeeper分布式部署PHP应用程序
2019/03/15 PHP
laravel中数据显示方法(默认值和下拉option默认选中)
2019/10/11 PHP
浅谈Laravel中的三种中间件的作用
2019/10/13 PHP
脚本合并提升javascript性能示例
2014/02/24 Javascript
Nodejs极简入门教程(一):模块机制
2014/10/25 NodeJs
JS实现网页背景颜色与select框中颜色同时变化的方法
2015/02/27 Javascript
js控制元素显示在屏幕固定位置及监听屏幕高度变化的方法
2015/08/11 Javascript
Javascript中的几种继承方式对比分析
2016/03/22 Javascript
微信小程序 textarea 组件详解及简单实例
2017/01/10 Javascript
Bootstrap Fileinput 4.4.7文件上传实例详解
2018/07/25 Javascript
爬虫利器Puppeteer实战
2019/01/09 Javascript
微信小程序顶部导航栏可滑动并选中放大
2019/12/05 Javascript
vue组件传值的实现方式小结【三种方式】
2020/02/05 Javascript
浅析vue cli3 封装Svgicon组件正确姿势(推荐)
2020/04/27 Javascript
vue 使用lodash实现对象数组深拷贝操作
2020/09/10 Javascript
[22:59]VGJ.S vs VG 2018国际邀请赛小组赛BO2 第二场 8.16
2018/08/17 DOTA
[44:22]完美世界DOTA2联赛循环赛 FTD vs PXG BO2第一场 11.01
2020/11/02 DOTA
使用python调用浏览器并打开一个网址的例子
2014/06/05 Python
python实现马耳可夫链算法实例分析
2015/05/20 Python
Python实现霍夫圆和椭圆变换代码详解
2018/01/12 Python
Python实现PS图像抽象画风效果的方法
2018/01/23 Python
TensorFlow实现卷积神经网络CNN
2018/03/09 Python
Python根据指定日期计算后n天,前n天是哪一天的方法
2018/05/29 Python
CSS3的Border-radius轻松制作圆角
2012/12/24 HTML / CSS
澳大利亚吉他在线:Artist Guitars
2017/03/30 全球购物
安踏官方商城:anta.cn
2019/12/16 全球购物
澳大利亚在线奢侈品时尚零售平台:Azura Runway
2021/01/13 全球购物
Linux面试题LINUX系统类
2014/11/19 面试题
投标单位介绍信
2014/01/09 职场文书
团组织关系介绍信
2014/01/12 职场文书
2013年军训通讯稿
2014/02/05 职场文书
新手上路标语
2014/06/20 职场文书
外贸业务员岗位职责
2015/02/13 职场文书