详解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 添加/移除CSS类实现代码
Feb 11 Javascript
jQuery选择器中含有空格的使用示例及注意事项
Aug 25 Javascript
捕获和分析JavaScript Error的方法
Mar 25 Javascript
Javascript中的关键字和保留字整理
Oct 16 Javascript
jQuery使用fadein方法实现渐出效果实例
Mar 27 Javascript
jQuery实现折叠、展开的菜单组效果代码
Sep 16 Javascript
使用JS实现图片展示瀑布流效果的实例代码
Sep 12 Javascript
用js写的一个路由(简单实例)
Sep 24 Javascript
浅谈Vue的基本应用
Dec 27 Javascript
Angular动态添加、删除输入框并计算值实例代码
Mar 29 Javascript
使用JavaScript实现在页面中显示距离2017年中秋节的天数
Sep 26 Javascript
vue打包通过image-webpack-loader插件对图片压缩优化操作
Nov 12 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
咖啡知识大全
2021/03/03 新手入门
PHP的历史和优缺点
2006/10/09 PHP
php 攻击方法之谈php+mysql注射语句构造
2009/10/30 PHP
phpmyadmin出现Cannot start session without errors问题解决方法
2014/08/14 PHP
thinkphp获取栏目和文章当前位置的方法
2014/10/29 PHP
PHP生成不重复标识符的方法
2014/11/21 PHP
PHPstorm激活码2020年5月13日亲测有效
2020/09/17 PHP
JS 常用校验函数
2009/03/26 Javascript
编写自己的jQuery插件简单实现代码
2011/04/19 Javascript
动态创建样式表在各浏览器中的差异测试代码
2011/09/13 Javascript
使用jquery获取网页中图片高度的两种方法
2013/09/26 Javascript
js随机生成网页背景颜色的方法
2015/02/26 Javascript
浅谈JavaScript的事件
2015/02/27 Javascript
Eclipse编辑jsp、js文件时卡死现象的解决办法汇总
2016/02/02 Javascript
AngularJS实践之使用ng-repeat中$index的注意点
2016/12/22 Javascript
nodejs的压缩文件模块archiver用法示例
2017/01/18 NodeJs
Vue组件tree实现树形菜单
2017/04/13 Javascript
vue之debounce属性被移除及处理详解
2019/11/13 Javascript
Vue管理系统前端之组件拆分封装详解
2020/08/23 Javascript
Vue this.$router.push(参数)实现页面跳转操作
2020/09/09 Javascript
vue中watch的用法汇总
2020/12/28 Vue.js
简单的通用表达式求10乘阶示例
2014/03/03 Python
详解Python的Twisted框架中reactor事件管理器的用法
2016/05/25 Python
Python matplotlib画图实例之绘制拥有彩条的图表
2017/12/28 Python
Python获取数据库数据并保存在excel表格中的方法
2019/06/12 Python
python制作简单五子棋游戏
2019/06/18 Python
你还在@微信官方?聊聊Python生成你想要的微信头像
2019/09/25 Python
如何使用python写截屏小工具
2020/09/29 Python
在阿尔卑斯山或希腊度过快乐假期:Alpine Elements
2019/12/28 全球购物
欧姆龙医疗欧洲有限公司:Omron Healthcare Europe B.V
2020/06/13 全球购物
Internet体系结构
2014/12/21 面试题
商务会议邀请函
2014/01/09 职场文书
同学聚会欢迎辞
2014/01/14 职场文书
员工安全生产责任书
2014/07/22 职场文书
2019年关于小学生课外阅读情况的分析报告
2019/12/02 职场文书
Web前端:CSS最强总结 附详细代码
2021/03/31 HTML / CSS