详解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之Document元素选择器篇
Aug 14 Javascript
js 效率组装字符串 StringBuffer
Dec 23 Javascript
JS延迟加载(setTimeout) JS最后加载
Jul 15 Javascript
js实现文章文字大小字号功能完整实例
Nov 01 Javascript
node.js中的http.response.write方法使用说明
Dec 14 Javascript
JS中用try catch对代码运行的性能影响分析
Dec 26 Javascript
详解Vue中组件的缓存
Apr 20 Javascript
微信小程序 Storage更新详解
Jul 16 Javascript
Vue实现商品分类菜单数量提示功能
Jul 26 Javascript
Vue filter 过滤当前时间 实现实时更新效果
Dec 20 Javascript
基于jsbarcode 生成条形码并将生成的条码保存至本地+源码
Apr 27 Javascript
vue 自定义的组件绑定点击事件
Apr 21 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
摩卡咖啡
2021/03/03 咖啡文化
php连接mysql数据库
2017/03/21 PHP
ThinkPHP 模板引擎使用详解
2017/05/07 PHP
thinkPHP3.2.3实现阿里大于短信验证的方法
2018/06/06 PHP
PHP safe_mode开启对于PHP系统函数有什么影响
2020/11/10 PHP
类似框架的js代码
2006/11/09 Javascript
Div Select挡住的解决办法
2008/08/07 Javascript
javascript hashtable实现代码
2009/10/13 Javascript
JQuery小知识
2010/10/15 Javascript
javascript实现焦点滚动图效果 具体方法
2013/06/24 Javascript
快速解决FusionCharts联动的中文乱码问题
2013/12/04 Javascript
Javascript删除指定元素节点的方法
2016/06/21 Javascript
微信js-sdk预览图片接口及从拍照或手机相册中选图接口用法示例
2016/10/13 Javascript
jQuery Easy UI中根据第一个下拉框选中的值设置第二个下拉框是否可以编辑
2016/11/29 Javascript
Jquery Easyui自定义下拉框组件使用详解(21)
2020/12/31 Javascript
微信小程序 摇一摇抽奖简单实例实现代码
2017/01/09 Javascript
vue一步步实现alert功能
2017/07/05 Javascript
详解Node.js模板引擎Jade入门
2018/01/19 Javascript
详解简单易懂的 ES6 Iterators 指南和示例
2019/09/24 Javascript
关于Vue中axios的封装实例详解
2019/10/20 Javascript
让mocha支持ES6模块的方法实现
2020/01/14 Javascript
[39:21]LGD vs OG 2019国际邀请赛淘汰赛 胜者组 BO3 第二场 8.24
2019/09/10 DOTA
Python读写ini文件的方法
2015/05/28 Python
Python实现高效求解素数代码实例
2015/06/30 Python
利用python模拟sql语句对员工表格进行增删改查
2017/07/05 Python
详谈pandas中agg函数和apply函数的区别
2018/04/20 Python
python 读取目录下csv文件并绘制曲线v111的方法
2018/07/06 Python
python3获取文件中url内容并下载代码实例
2019/12/27 Python
Viking比利时:购买办公用品
2019/10/30 全球购物
女娲补天教学反思
2014/02/05 职场文书
《都江堰》教学反思
2014/02/07 职场文书
委托书怎么写
2014/07/31 职场文书
四十年同学聚会致辞
2015/07/28 职场文书
《自己去吧》教学反思
2016/02/16 职场文书
Python OpenCV 彩色与灰度图像的转换实现
2021/06/05 Python
JPA 通过Specification如何实现复杂查询
2021/11/23 Java/Android