详解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 相关文章推荐
extjs中form与grid交互数据(record)的方法
Aug 29 Javascript
详谈javascript中的cookie
Jun 03 Javascript
input file上传 图片预览功能实例代码
Oct 25 Javascript
canvas 画布在主流浏览器中的尺寸限制详细介绍
Dec 15 Javascript
Vue.js实战之组件的进阶
Apr 04 Javascript
本地搭建微信小程序服务器的实现方法
Oct 27 Javascript
vue实现2048小游戏功能思路详解
May 09 Javascript
利用Webpack实现小程序多项目管理的方法
Feb 25 Javascript
浅谈JavaScript闭包
Apr 09 Javascript
微信小程序转发事件实现解析
Oct 22 Javascript
vue实现移动端图片上传功能
Dec 23 Javascript
基于vue+echarts数据可视化大屏展示的实现
Dec 25 Vue.js
详解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
全国FM电台频率大全 - 1 北京市
2020/03/11 无线电
收集的php编写大型网站问题集
2007/03/06 PHP
php下实现伪 url 的超简单方法[转]
2007/09/24 PHP
Yii中render和renderPartial的区别
2014/09/03 PHP
PHP基于面向对象实现的留言本功能实例
2018/04/04 PHP
jQuery学习7 操作JavaScript对象和集合的函数
2010/02/07 Javascript
jquery validate添加自定义验证规则(验证邮箱 邮政编码)
2013/12/04 Javascript
谈谈javascript中使用连等赋值操作带来的问题
2015/11/26 Javascript
基于javascript如何传递特殊字符
2015/11/30 Javascript
Angular实现form自动布局
2016/01/28 Javascript
javascript中sort排序实例详解
2016/07/24 Javascript
详解js中的apply与call的用法
2016/07/30 Javascript
工厂模式在JS中的实践
2017/01/18 Javascript
jQuery条件分页 代替离线查询(附代码)
2017/08/17 jQuery
AngularJS 的$timeout服务示例代码
2017/09/21 Javascript
js和jQuery以及easyui实现对下拉框的指定赋值方法
2018/01/23 jQuery
微信小程序的部署方法步骤
2018/09/04 Javascript
vue中v-text / v-html使用实例代码详解
2019/04/02 Javascript
了解JavaScript表单操作和表单域
2019/05/27 Javascript
vue中后端做Excel导出功能返回数据流前端的处理操作
2020/09/08 Javascript
python微信公众号开发简单流程
2018/03/23 Python
Django-rest-framework中过滤器的定制实例
2020/04/01 Python
pytorch 中forward 的用法与解释说明
2021/02/26 Python
Python使用Turtle模块绘制国旗的方法示例
2021/02/28 Python
用CSS3的box-reflect来制作倒影效果
2016/11/15 HTML / CSS
C# Debug和Testing相关面试题
2015/10/25 面试题
Servlet如何得到客户端机器的信息
2014/10/17 面试题
建筑装饰学院室内设计专业个人自我评价
2013/12/07 职场文书
检讨书格式
2015/05/07 职场文书
刑事起诉书范文
2015/05/19 职场文书
Python竟然能剪辑视频
2021/05/25 Python
教你使用Python pypinyin库实现汉字转拼音
2021/05/27 Python
python实现股票历史数据可视化分析案例
2021/06/10 Python
Python实现猜拳与猜数字游戏的方法详解
2022/04/06 Python
Java8 Stream API 提供了一种高效且易于使用的处理数据的方式
2022/04/13 Java/Android
canvas 中如何实现物体的框选
2022/08/05 Javascript