详解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代码
Oct 19 Javascript
基于Jquery的回车成tab焦点切换效果代码(Enter To Tab )
Nov 14 Javascript
JS获取下拉列表所选中的TEXT和Value的实现代码
Jan 11 Javascript
jQuery中事件对象e的事件冒泡用法示例介绍
Apr 25 Javascript
Iframe实现跨浏览器自适应高度解决方法
Sep 02 Javascript
jQuery 中$(this).index与$.each的使用指南
Nov 20 Javascript
JavaScript生成随机字符串的方法
Mar 19 Javascript
Input文本框随着输入内容多少自动延伸的实现
Feb 15 Javascript
node.js中实现kindEditor图片上传功能的方法教程
Apr 26 Javascript
jQuery操作DOM_动力节点Java学院整理
Jul 04 jQuery
Vue.directive 自定义指令的问题小结
Mar 04 Javascript
基于Vue的延迟加载插件vue-view-lazy
May 21 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
Flash空降上海 化身大魔王接受挑战
2020/03/02 星际争霸
php根据年月获取季度的方法
2014/03/31 PHP
PHP执行Curl时报错提示CURL ERROR: Recv failure: Connection reset by peer的解决方法
2014/06/26 PHP
Laravel 简单实现Ajax滚动加载示例
2019/10/22 PHP
jquery 添加节点的几种方法介绍
2013/09/04 Javascript
jquery插件推荐 jquery.cookie
2014/11/09 Javascript
JavaScript给input的value赋值引发的关于基本类型值和引用类型值问题
2015/12/07 Javascript
JS多物体实现缓冲运动效果示例
2016/12/20 Javascript
简单实现JS倒计时效果
2016/12/23 Javascript
jQuery实现页面顶部下拉广告
2016/12/30 Javascript
JavaScript全屏和退出全屏事件总结(附代码)
2017/08/17 Javascript
JS设计模式之访问者模式定义与用法分析
2018/02/05 Javascript
微信小程序实现的点击按钮 弹出底部上拉菜单功能示例
2018/12/20 Javascript
js遍历详解(forEach, map, for, for...in, for...of)
2019/08/28 Javascript
解决layui数据表格table的横向滚动条显示问题
2019/09/04 Javascript
vue实现百度搜索功能
2020/12/28 Javascript
CountUp.js数字滚动插件使用方法详解
2019/10/17 Javascript
JavaScript 实现HTML DOM增删改查操作的常见方法详解
2020/01/04 Javascript
实例讲解Python中global语句下全局变量的值的修改
2016/06/16 Python
简单了解python模块概念
2018/01/11 Python
Python3.5面向对象与继承图文实例详解
2019/04/24 Python
Python利用Scrapy框架爬取豆瓣电影示例
2020/01/17 Python
Html5游戏开发之乒乓Ping Pong游戏示例(三)
2013/01/21 HTML / CSS
信息专业本科生个人的自我评价
2013/10/28 职场文书
日语专业毕业生自荐信
2013/11/11 职场文书
人事专员工作职责
2014/02/22 职场文书
舞蹈专业大学生职业规划范文
2014/03/12 职场文书
乡镇党的群众路线教育实践活动领导班子对照检查材料
2014/09/25 职场文书
教师作风整顿个人剖析材料
2014/10/10 职场文书
深入开展党的群众路线教育实践活动心得体会
2014/11/05 职场文书
新郎答谢词
2015/01/04 职场文书
升职自荐信怎么写
2015/03/05 职场文书
2015年端午节国旗下演讲稿
2015/03/19 职场文书
英语教师求职信范文
2015/03/20 职场文书
英语演讲开场白
2015/05/29 职场文书
windows server2012 R2下安装PaddleOCR服务的的详细步骤
2022/09/23 Servers