详解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 选项卡效果(JS与HTML的分离)
Apr 01 Javascript
jQuery之日期选择器的深入解析
Jun 19 Javascript
javascript验证只能输入数字和一个小数点示例
Oct 21 Javascript
JavaScript取得WEB安全颜色列表的方法
Jul 14 Javascript
纯jquery实现模仿淘宝购物车结算
Aug 20 Javascript
JS中如何实现Laravel的route函数详解
Feb 12 Javascript
Vue.js原理分析之observer模块详解
Feb 17 Javascript
JavaScript定义函数的三种实现方法
Sep 23 Javascript
vue自动路由-单页面项目(非build时构建)
Apr 30 Javascript
详解Webpack如何引入CDN链接来优化编译后的体积
Jun 21 Javascript
微信小程序实现点击空白隐藏的方法示例
Aug 13 Javascript
浅谈Vue3 Composition API如何替换Vue Mixins
Apr 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
phpmyadmin3 安装配置图解教程
2012/03/29 PHP
PHP文件去掉PHP注释空格的函数分析(PHP代码压缩)
2013/07/02 PHP
javascript 浏览器判断 绑定事件 arguments 转换数组 数组遍历
2009/07/06 Javascript
判断控件是否已加载完成的代码
2010/02/24 Javascript
javascript截取字符串(通过substring实现并支持中英文混合)
2013/06/24 Javascript
jquery easyui滚动条部分设置介绍
2013/09/12 Javascript
jQuery事件绑定和委托实例
2014/11/25 Javascript
jQuery中triggerHandler()方法用法实例
2015/01/19 Javascript
JavaSciprt中处理字符串之sup()方法的使用教程
2015/06/08 Javascript
jquery+CSS实现的多级竖向展开树形TRee菜单效果
2015/08/24 Javascript
jQuery实现简单的列表式导航菜单效果代码
2015/08/31 Javascript
vueJS简单的点击显示与隐藏的效果【实现代码】
2016/05/03 Javascript
原生JS发送异步数据请求
2017/06/08 Javascript
angular4自定义组件详解
2017/09/28 Javascript
三分钟学会用ES7中的Async/Await进行异步编程
2018/06/14 Javascript
vue中引用swiper轮播插件的教程详解
2018/08/16 Javascript
vue3.0 CLI - 2.6 - 组件的复用入门教程
2018/09/14 Javascript
JS实现十分钟倒计时代码实例
2018/10/18 Javascript
8个有意思的JavaScript面试题
2019/07/30 Javascript
vue使用一些外部插件及样式的配置代码
2019/11/18 Javascript
JS运算符优先级与表达式示例详解
2020/09/04 Javascript
python使用PyGame模块播放声音的方法
2015/05/20 Python
Python中基本的日期时间处理的学习教程
2015/10/16 Python
python飞机大战pygame游戏背景设计详解
2019/12/17 Python
python使用turtle库绘制奥运五环
2020/02/24 Python
重写django的model下的objects模型管理器方式
2020/05/15 Python
Python xpath表达式如何实现数据处理
2020/06/13 Python
Python3爬虫中Selenium的用法详解
2020/07/10 Python
班级活动策划书
2014/02/06 职场文书
文明餐桌活动方案
2014/02/11 职场文书
幼儿园优秀教师事迹
2014/02/13 职场文书
六查六看个人剖析材料
2014/10/14 职场文书
群众路线专项整治方案
2014/10/27 职场文书
优秀班主任申报材料
2014/12/16 职场文书
Nginx内网单机反向代理的实现
2021/11/07 Servers
JavaScript的Set数据结构详解
2022/02/18 Javascript