详解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 相关文章推荐
JS 强制设为首页的代码
Jan 31 Javascript
jquery select选中的一个小问题
Oct 11 Javascript
js实现网站最上边可关闭的浮动广告条代码
Sep 04 Javascript
jquery实现垂直和水平菜单导航栏
Aug 27 Javascript
angularjs使用directive实现分页组件的示例
Feb 07 Javascript
PHP实现本地图片上传和验证功能
Feb 27 Javascript
JavaScript实现选中文字提示新浪微博分享效果
Jun 15 Javascript
angular $watch 一个变量的变化(实例讲解)
Aug 02 Javascript
基于es6三点运算符的使用方法(实例讲解)
Oct 12 Javascript
微信小程序 textarea 层级过高问题简单解决方案
Oct 14 Javascript
浅谈关于vue中scss公用的解决方案
Dec 02 Javascript
JS组件库AlloyTouch实现图片轮播过程解析
May 29 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
配置Apache2.2+PHP5+CakePHP1.2+MySQL5运行环境
2009/04/25 PHP
PHP嵌套输出缓冲代码实例
2015/05/12 PHP
jQuery 1.0.4 - New Wave Javascript(js源文件)
2007/01/15 Javascript
客户端js性能优化小技巧整理
2013/11/05 Javascript
jquery 使用简明教程
2014/03/05 Javascript
AngularJS入门教程(零):引导程序
2014/12/06 Javascript
JavaScript encodeURI 和encodeURIComponent
2015/12/04 Javascript
理解JavaScript中worker事件api
2015/12/25 Javascript
详解JavaScript的AngularJS框架中的作用域与数据绑定
2016/03/04 Javascript
利用javascript如何随机生成一定位数的密码
2017/09/22 Javascript
vue组件中使用iframe元素的示例代码
2017/12/13 Javascript
详解Vue调用手机相机和相册以及上传
2019/05/05 Javascript
js实现的格式化数字和金额功能简单示例
2019/07/30 Javascript
《javascript设计模式》学习笔记一:Javascript面向对象程序设计对象成员的定义分析
2020/04/07 Javascript
vue+Element-ui前端实现分页效果
2020/11/15 Javascript
k8s node节点重新加入master集群的实现
2021/02/22 Javascript
[34:39]Secret vs VG 2018国际邀请赛淘汰赛BO3 第二场 8.23
2018/08/24 DOTA
[01:23]2019完美世界全国高校联赛(春季赛)合肥全国总决赛
2019/06/10 DOTA
在MAC上搭建python数据分析开发环境
2016/01/26 Python
完美解决安装完tensorflow后pip无法使用的问题
2018/06/11 Python
详解Python3中ceil()函数用法
2019/02/19 Python
pandas 选取行和列数据的方法详解
2019/08/08 Python
python遍历路径破解表单的示例
2020/11/21 Python
解析HTML5中的新功能本地存储localStorage
2016/03/01 HTML / CSS
HTML5 新标签全部总汇(推荐)
2016/06/13 HTML / CSS
HTML5在手机端实现视频全屏展示方法
2020/11/23 HTML / CSS
国际旅客访问北美最大的汽车租赁提供商:Alamo Rent A Car
2018/06/13 全球购物
《花木兰》教学反思
2014/04/09 职场文书
综治工作心得体会
2014/09/11 职场文书
服务明星事迹材料
2014/12/29 职场文书
社区艾滋病宣传活动总结
2015/05/07 职场文书
医疗纠纷调解协议书
2015/08/06 职场文书
《老人与海鸥》教学反思
2016/02/16 职场文书
2016年最美孝心少年事迹材料
2016/02/26 职场文书
Redis 操作多个数据库的配置的方法实现
2022/03/23 Redis
MySQL索引 高效获取数据的数据结构
2022/05/02 MySQL