详解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.ui.draggable中文文档
Nov 24 Javascript
js跨浏览器的事件侦听器和事件对象的使用方法
Dec 17 Javascript
去除html代码里面的script正则方法
May 19 Javascript
jquery计算出left和top,让一个div水平垂直居中的简单实例
Jul 13 Javascript
canvas绘制多边形
Feb 24 Javascript
Angular中自定义Debounce Click指令防止重复点击
Jul 26 Javascript
带你快速理解javascript中的事件模型
Aug 14 Javascript
Vue-router 类似Vuex实现组件化开发的示例
Sep 15 Javascript
详解基于node.js的脚手架工具开发经历
Jan 28 Javascript
微信小程序 生成携带参数的二维码
Oct 23 Javascript
VUE:vuex 用户登录信息的数据写入与获取方式
Nov 11 Javascript
Webpack的Loader和Plugin的区别
Nov 09 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中使用PDF文档功能
2006/10/09 PHP
Win2003+apache+PHP+SqlServer2008 配置生产环境
2014/07/29 PHP
PHP CURL 内存泄露问题解决方法
2015/02/12 PHP
thinkphp利用模型通用数据编辑添加和删除的实例代码
2016/11/20 PHP
这些年、我收集的JQuery代码小结
2012/08/01 Javascript
使用jQueryMobile实现滑动翻页效果的方法
2015/02/04 Javascript
ECMAScript6块级作用域及新变量声明(let)
2015/06/12 Javascript
纯jquery实现模仿淘宝购物车结算
2015/08/20 Javascript
ztree简介_动力节点Java学院整理
2017/07/19 Javascript
超级简易的JS计算器实例讲解(实现加减乘除)
2017/08/08 Javascript
教你使用vue-cli快速构建的小说阅读器
2019/05/13 Javascript
JavaScript简单编程实例学习
2020/02/14 Javascript
js实现跳一跳小游戏
2020/07/31 Javascript
Python Paramiko模块的安装与使用详解
2016/11/18 Python
python发送邮件实例分享
2017/07/28 Python
python生成tensorflow输入输出的图像格式的方法
2018/02/12 Python
对python以16进制打印字节数组的方法详解
2019/01/24 Python
Python元组常见操作示例
2019/02/19 Python
nginx搭建基于python的web环境的实现步骤
2020/01/03 Python
Pytorch在dataloader类中设置shuffle的随机数种子方式
2020/01/14 Python
python读取文件指定行内容实例讲解
2020/03/02 Python
使用numpngw和matplotlib生成png动画的示例代码
2021/01/24 Python
HTML5 语音搜索只需一句代码
2013/01/03 HTML / CSS
HTML5 form标签之解放表单验证、增加文件上传、集成拖放的使用方法
2013/04/24 HTML / CSS
html5拖拽应用记录及注意点
2020/05/27 HTML / CSS
ProBikeKit美国官网:自行车套件,跑步和铁人三项套件
2016/10/13 全球购物
戴森香港官方网站:Dyson香港
2021/02/11 全球购物
乡镇三项教育实施方案
2014/03/30 职场文书
《狼和小羊》教学反思
2014/04/20 职场文书
道德之星事迹材料
2014/05/03 职场文书
股权转让协议书
2014/12/07 职场文书
研究生导师推荐信
2015/03/25 职场文书
写给女朋友的保证书
2015/05/09 职场文书
win11怎么用快捷键锁屏? windows11锁屏的几种方法
2021/11/21 数码科技
MySQL中B树索引和B+树索引的区别详解
2022/03/03 MySQL
Android中View.post和Handler.post的关系
2022/06/05 Java/Android