详解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文件缓存的代码
Apr 09 Javascript
Ajax 数据请求的简单分析
Apr 05 Javascript
javascript学习笔记(七)利用javascript来创建和存储cookie
Apr 08 Javascript
JavaScript基础语法让人疑惑的地方小结
May 23 Javascript
JavaScript 操作table,可以新增行和列并且隔一行换背景色代码分享
Jul 05 Javascript
当鼠标移动时出现特效的JQuery代码
Nov 08 Javascript
JS实现文字放大效果的方法
Mar 03 Javascript
简单了解JavaScript操作XPath的一些基本方法
Jun 03 Javascript
Angularjs 创建可复用组件实例代码
Oct 09 Javascript
Vue.js实现分页查询功能
Nov 15 Javascript
AngularJS自定义表单验证功能实例详解
Aug 24 Javascript
详解在微信小程序的JS脚本中使用Promise来优化函数处理
Mar 06 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实现域名whois查询的代码(数据源万网、新网)
2010/02/22 PHP
php将mysql数据库整库导出生成sql文件的具体实现
2014/01/08 PHP
PHP中读取文件的几个方法总结(推荐)
2016/06/03 PHP
php实现在线考试系统【附源码】
2018/09/18 PHP
PHP asXML()函数讲解
2019/02/03 PHP
jquery中focus()函数实现当对象获得焦点后自动把光标移到内容最后
2013/09/29 Javascript
使用js画图之饼图
2015/01/12 Javascript
jQuery功能函数详解
2015/02/01 Javascript
JS排序之快速排序详解
2017/04/08 Javascript
nodejs处理图片的中间件node-images详解
2017/05/08 NodeJs
微信小程序的日期选择器的实例详解
2017/09/29 Javascript
Vue2.0 axios前后端登陆拦截器(实例讲解)
2017/10/27 Javascript
angular4 共享服务在多个组件中数据通信的示例
2018/03/30 Javascript
nodejs实现的http、https 请求封装操作示例
2020/02/06 NodeJs
JavaScript中break、continue和return的用法区别实例分析
2020/03/02 Javascript
Python实现的插入排序算法原理与用法实例分析
2017/11/22 Python
python+tkinter编写电脑桌面放大镜程序实例代码
2018/01/16 Python
python opencv检测目标颜色的实例讲解
2018/04/02 Python
使用python批量读取word文档并整理关键信息到excel表格的实例
2018/11/07 Python
Python按钮的响应事件详解
2019/03/04 Python
django框架model orM使用字典作为参数,保存数据的方法分析
2019/06/24 Python
使用python模拟命令行终端的示例
2019/08/13 Python
Python Celery多队列配置代码实例
2019/11/22 Python
python识别验证码图片实例详解
2020/02/17 Python
Python 抓取数据存储到Redis中的操作
2020/07/16 Python
Python unittest discover批量执行代码实例
2020/09/08 Python
python 基于opencv 绘制图像轮廓
2020/12/11 Python
宝塔面板出现“open_basedir restriction in effect. ”的解决方法
2021/03/14 PHP
世界上最大的乐谱选择:Sheet Music Plus
2020/01/18 全球购物
机械制造与自动化应届生求职信
2013/11/16 职场文书
最新的咖啡店创业计划书
2013/12/30 职场文书
幼儿教师师德师风演讲稿
2014/08/22 职场文书
2016中秋晚会开幕词
2016/03/03 职场文书
2019奶茶店创业计划书范本,值得你借鉴
2019/08/14 职场文书
分享Python异步爬取知乎热榜
2022/04/12 Python
HTML 里 img 元素的 src 和 srcset 属性的区别详解
2023/05/21 HTML / CSS