详解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 相关文章推荐
下载网站打开页面后间隔多少时间才显示下载链接地址的代码
Apr 25 Javascript
javascript之通用简单的table选项卡实现(二)
May 09 Javascript
基于JQuery的访问WebService的代码(可访问Java[Xfire])
Nov 19 Javascript
js关闭子窗体刷新父窗体实现方法
Dec 04 Javascript
JS实现时间格式化的方式汇总
Oct 16 Javascript
弹出最简单的模式化遮罩层的js代码
Dec 04 Javascript
append和appendTo的区别以及appendChild用法
Dec 24 Javascript
js之ActiveX控件使用说明 new ActiveXObject()
Mar 03 Javascript
js获取指定日期周数以及星期几的小例子
Jun 27 Javascript
Vue头像处理方案小结
Jul 26 Javascript
JS使用Prim算法和Kruskal算法实现最小生成树
Jan 17 Javascript
通过实践编写优雅的JavaScript代码
May 30 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
从C/C++迁移到PHP——判断字符类型的函数
2006/10/09 PHP
PHP使用Alexa API获取网站的Alexa排名例子
2014/06/12 PHP
php使用PDO方法详解
2014/12/27 PHP
php超快高效率统计大文件行数
2015/07/05 PHP
php实现微信企业号支付个人的方法详解
2017/07/26 PHP
javascript 跨浏览器开发经验总结(五) js 事件
2010/05/19 Javascript
JavaScript调用堆栈及setTimeout使用方法深入剖析
2013/02/16 Javascript
关于Jquery操作Cookie取值错误的解决方法
2013/08/26 Javascript
jQuery控制的不同方向的滑动(向左、向右滑动等)
2014/07/18 Javascript
使用Node.js实现HTTP 206内容分片的教程
2015/06/23 Javascript
javascript闭包(Closure)用法实例简析
2015/11/30 Javascript
基于Vuejs框架实现翻页组件
2020/06/29 Javascript
jQuery实现简单的手风琴效果
2020/04/17 jQuery
node中使用es5/6以及支持性与性能对比
2017/08/11 Javascript
webpack使用 babel-loader 转换 ES6代码示例
2017/08/21 Javascript
webpack学习笔记之优化缓存、合并、懒加载
2017/08/24 Javascript
JS基于对象的特性实现去除数组中重复项功能详解
2017/11/17 Javascript
原生javascript AJAX 三级联动的实现代码
2018/05/04 Javascript
Vue项目中跨域问题解决方案
2018/06/05 Javascript
vue解决弹出蒙层滑动穿透问题的方法
2018/09/22 Javascript
vue实现吸顶、锚点和滚动高亮按钮效果
2019/10/21 Javascript
Python接收Gmail新邮件并发送到gtalk的方法
2015/03/10 Python
python中enumerate函数用法实例分析
2015/05/20 Python
Python错误提示:[Errno 24] Too many open files的分析与解决
2017/02/16 Python
使用pandas模块读取csv文件和excel表格,并用matplotlib画图的方法
2018/06/22 Python
浅析python3字符串格式化format()函数的简单用法
2018/12/07 Python
Python爬虫破解登陆哔哩哔哩的方法
2020/11/17 Python
css3实现3D色子翻转特效
2014/12/23 HTML / CSS
CSS3中的display:grid,网格布局介绍
2019/10/30 HTML / CSS
Java程序开发中如何应用线程
2016/03/03 面试题
企业员工薪酬方案
2014/06/04 职场文书
机械加工与数控专业自荐书
2014/06/04 职场文书
计算机专业自荐信
2015/03/05 职场文书
2015年行政人事部工作总结
2015/05/13 职场文书
2015年教师节广播稿
2015/08/19 职场文书
Python GUI编程之tkinter 关于 ttkbootstrap 的使用详解
2022/03/03 Python