详解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 简单导航实现代码
Sep 11 Javascript
javascript 事件处理程序介绍
Jun 27 Javascript
JavaScript中使用ActiveXObject操作本地文件夹的方法
Mar 28 Javascript
node.js中的console用法总结
Dec 15 Javascript
jQuery+HTML5美女瀑布流布局实现方法
Sep 21 Javascript
使用递归遍历对象获得value值的实现方法
Jun 14 Javascript
JS中使用mailto实现将用户在网页中输入的内容传递到本地邮件客户端
Oct 08 Javascript
js 动态生成html 触发事件传参字符转义的实例
Feb 14 Javascript
详谈js中标准for循环与foreach(for in)的区别
Nov 02 Javascript
jsonp跨域获取数据的基础教程
Jul 01 Javascript
Vue组件通信入门之Provide和Inject机制
Dec 29 Javascript
Vue项目中使用mock.js的完整步骤
Jan 12 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
咖啡豆分级制度 咖啡豆等级分类 咖啡豆是按口感分类的吗?
2021/03/05 新手入门
php编写的一个E-mail验证类
2015/03/25 PHP
apache和PHP如何整合在一起
2015/10/12 PHP
实例讲解PHP验证邮箱是否合格
2019/01/28 PHP
jQuery让控件左右移动的三种实现方法
2013/09/08 Javascript
JS网页播放声音实现代码兼容各种浏览器
2013/09/22 Javascript
jQuery中val()方法用法实例
2014/12/25 Javascript
2014 年最热门的21款JavaScript框架推荐
2014/12/25 Javascript
Javascript中3个需要注意的运算符
2015/04/02 Javascript
Jquery日期选择datepicker插件用法实例分析
2015/06/08 Javascript
实例讲解JavaScript中instanceof运算符的用法
2016/06/08 Javascript
js select实现省市区联动选择
2020/04/17 Javascript
前端框架Vue.js中Directive知识详解
2016/09/12 Javascript
vue全局组件与局部组件使用方法详解
2018/03/29 Javascript
vue实现打印功能的两种方法
2018/09/07 Javascript
在angularJs中进行数据遍历的2种方法
2018/10/08 Javascript
在vue中阻止浏览器后退的实例
2019/11/06 Javascript
[56:57]LGD vs VP 2019DOTA2国际邀请赛淘汰赛 胜者组赛BO3 第一场 8.20.mp4
2019/08/22 DOTA
Python中的__slots__示例详解
2017/07/06 Python
利用Python批量压缩png方法实例(支持过滤个别文件与文件夹)
2017/07/30 Python
python的concat等多种用法详解
2018/11/28 Python
Python爬取爱奇艺电影信息代码实例
2019/11/26 Python
python3.7+selenium模拟淘宝登录功能的实现
2020/05/26 Python
Python单元测试及unittest框架用法实例解析
2020/07/09 Python
python批量修改文件名的示例
2020/09/27 Python
Pycharm同步远程服务器调试的方法步骤
2020/11/04 Python
详解css3中 text-fill-color属性
2019/07/08 HTML / CSS
房屋转让协议书范本
2014/04/11 职场文书
租车协议书范本2014
2014/11/17 职场文书
党员转正介绍人意见
2015/06/03 职场文书
医生行业员工的辞职信
2019/06/24 职场文书
2019最新企业员工考勤管理制度(通用版)!
2019/07/02 职场文书
2019安全宣传标语大全
2019/08/14 职场文书
利用 SQL Server 过滤索引提高查询语句的性能分析
2021/07/15 SQL Server
纯CSS打字动画的实现示例
2022/08/05 HTML / CSS