详解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 相关文章推荐
让浏览器非阻塞加载javascript的几种方法小结
Apr 25 Javascript
javascript与cookie 的问题详解
Nov 11 Javascript
jQuery中:has选择器用法实例
Dec 30 Javascript
jquery实现仿JqueryUi可拖动的DIV实例
Jul 31 Javascript
bootstrapValidator自定验证方法写法
Dec 01 Javascript
Javascript Function.prototype.bind详细分析
Dec 29 Javascript
微信小程序 判断手机号的实现代码
Apr 19 Javascript
JavaScript 数组去重并统计重复元素出现的次数实例
Dec 14 Javascript
使用javascript函数编写简单银行取钱存钱流程
May 26 Javascript
AngularJS $http post 传递参数数据的方法
Oct 09 Javascript
JavaScript判断对象和数组的两种方法
May 31 Javascript
Vue 实现CLI 3.0 + momentjs + lodash打包时优化
Nov 13 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
桌面中心(三)修改数据库
2006/10/09 PHP
PHP json_decode函数详细解析
2014/02/17 PHP
PHP的mysqli_query参数MYSQLI_STORE_RESULT和MYSQLI_USE_RESULT的区别
2014/09/29 PHP
关于WordPress的SEO优化相关的一些PHP页面脚本技巧
2015/12/10 PHP
php compact 通过变量创建数组
2016/11/15 PHP
PHP中模糊查询并关联三个select框
2017/06/19 PHP
PHP实现的下载远程文件类定义与用法示例
2017/07/05 PHP
Laravel中encrypt和decrypt的实现方法
2017/09/24 PHP
jQuery仿Flash上下翻动的中英文导航菜单实例
2015/03/10 Javascript
手机注册发送验证码倒计时的简单实例
2017/11/15 Javascript
vue 做移动端微信公众号采坑经验记录
2018/04/26 Javascript
关于JavaScript中高阶函数的魅力详解
2018/09/07 Javascript
详解小程序如何避免多次点击,重复触发事件
2019/04/08 Javascript
一个计算身份证号码校验位的Python小程序
2014/08/15 Python
基于Python实现一个简单的银行转账操作
2016/03/06 Python
Windows中使用wxPython和py2exe开发Python的GUI程序的实例教程
2016/07/11 Python
Python 安装setuptools和pip工具操作方法(必看)
2017/05/22 Python
python负载均衡的简单实现方法
2018/02/04 Python
CentOS 7下安装Python3.6 及遇到的问题小结
2018/11/08 Python
对Pytorch中nn.ModuleList 和 nn.Sequential详解
2019/08/18 Python
用Python将Excel数据导入到SQL Server的例子
2019/08/24 Python
Python计算不规则图形面积算法实现解析
2019/11/22 Python
使用Python第三方库pygame写个贪吃蛇小游戏
2020/03/06 Python
Html5与App的通讯方式详解
2019/10/24 HTML / CSS
浅析HTML5 Landmark
2020/09/11 HTML / CSS
施惠特软件测试面试题以及笔试题
2015/05/13 面试题
党支部书记岗位责任制
2014/02/11 职场文书
材料会计岗位职责
2014/03/06 职场文书
自我鉴定总结
2014/03/24 职场文书
铁路安全事故反思
2014/04/26 职场文书
2015年药房工作总结
2015/04/25 职场文书
2015年高校教师个人工作总结
2015/05/25 职场文书
2017年寒假社区服务活动总结
2016/04/06 职场文书
python本地文件服务器实例教程
2021/05/02 Python
golang实现一个简单的websocket聊天室功能
2021/10/05 Golang
分享CSS盒子模型隐藏的几种方式
2022/02/28 HTML / CSS