详解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中日期转换成时间戳的小例子
Mar 21 Javascript
Javascript中实现trim()函数的两种方法
Feb 04 Javascript
javascript结合CSS实现苹果开关按钮特效
Apr 07 Javascript
JS判断输入字符串长度实例代码(汉字算两个字符,字母数字算一个)
Aug 02 Javascript
15款最好的Bootstrap在线编辑器
Aug 03 Javascript
Html中 IFrame的用法及注意点
Dec 22 Javascript
jQuery实现联动下拉列表查询框
Jan 04 Javascript
Mint UI 基于 Vue.js 移动端组件库
Nov 07 Javascript
小程序开发基础之view视图容器
Aug 21 Javascript
基于Node.js的大文件分片上传示例
Jun 19 Javascript
vue实现图片上传到后台
Jun 29 Javascript
微信小程序APP的生命周期及页面的生命周期
Apr 19 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
php数组去重的函数代码
2013/02/03 PHP
推荐一款MAC OS X 下php集成开发环境mamp
2014/11/08 PHP
php计算税后工资的方法
2015/07/28 PHP
PHP爬虫之百万级别知乎用户数据爬取与分析
2016/01/22 PHP
php微信公众号开发之关键词回复
2018/10/20 PHP
Laravel重定向,a链接跳转,控制器跳转示例
2019/10/22 PHP
使用js解决由border属性引起的div宽度问题
2013/11/26 Javascript
node.js中的fs.lstatSync方法使用说明
2014/12/16 Javascript
JS中Location使用详解
2015/05/12 Javascript
JavaScript中的Math.SQRT1_2属性使用简介
2015/06/14 Javascript
jQuery实现的简单提示信息插件
2015/12/08 Javascript
jQuery控制div实现随滚动条滚动效果
2016/06/07 Javascript
简单分析javascript中的函数
2016/09/10 Javascript
mpvue微信小程序开发之实现一个弹幕评论
2019/11/24 Javascript
jquery将信息遍历到界面上实例代码
2020/01/21 jQuery
Vue axios获取token临时令牌封装案例
2020/09/11 Javascript
vue 中使用print.js导出pdf操作
2020/11/13 Javascript
vue实现滚动鼠标滚轮切换页面
2020/12/13 Vue.js
python有证书的加密解密实现方法
2014/11/19 Python
python 文件操作api(文件操作函数)
2016/08/28 Python
Python3.6笔记之将程序运行结果输出到文件的方法
2018/04/22 Python
python scp 批量同步文件的实现方法
2019/01/03 Python
python 多个参数不为空校验方法
2019/02/14 Python
详解python 利用echarts画地图(热力图)(世界地图,省市地图,区县地图)
2019/08/06 Python
Django rest framework jwt的使用方法详解
2019/08/08 Python
更新pip3与pyttsx3文字语音转换的实现方法
2019/08/08 Python
Python中函数的返回值示例浅析
2019/08/28 Python
pytorch中tensor.expand()和tensor.expand_as()函数详解
2019/12/27 Python
前端使用canvas生成盲水印的加密解密的实现
2020/12/16 HTML / CSS
尤为Wconcept中国官网:韩国设计师品牌服饰
2019/01/10 全球购物
武汉世纪畅想数字传播有限公司 .NET笔试题
2015/06/13 面试题
外科实习自我鉴定
2013/10/06 职场文书
经销商培训邀请函
2014/01/21 职场文书
个人授权委托书模板
2014/09/14 职场文书
新郎答谢词
2015/01/04 职场文书
个人催款函范文
2015/06/24 职场文书