详解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 相关文章推荐
超级强大的表单验证
Jun 26 Javascript
javascript 动态生成私有变量访问器
Dec 06 Javascript
javascript特殊用法示例介绍
Nov 29 Javascript
node.js中的fs.createReadStream方法使用说明
Dec 17 Javascript
浅析jQuery EasyUI中的tree使用指南
Dec 18 Javascript
基于javascript实现漂亮的页面过渡动画效果附源码下载
Oct 26 Javascript
JavaScript手机振动API
Jun 11 Javascript
javascript实现页面滚屏效果
Jan 17 Javascript
原生js实现对Ajax的封装(仿jquery)
Jan 22 Javascript
一步步教你利用webpack如何搭一个vue脚手架(超详细讲解和注释)
Jan 08 Javascript
微信小程序 如何引入外部字体库iconfont的图标
Jan 31 Javascript
JS实现生成由字母与数字组合的随机字符串功能详解
May 25 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中inlcude()性能对比详解
2012/09/16 PHP
file_get_contents(&quot;php://input&quot;, &quot;r&quot;)实例介绍
2013/07/01 PHP
javascript 控制弹出窗口
2007/04/10 Javascript
Jquery插件 easyUI属性汇总
2011/01/19 Javascript
事件冒泡是什么如何用jquery阻止事件冒泡
2013/03/20 Javascript
鼠标移动到图片名上,显示图片的简单实例
2013/07/14 Javascript
js监听键盘事件示例代码
2013/07/26 Javascript
jquery获取子节点和父节点的示例代码
2013/09/10 Javascript
基于jquery的simpleValidate简易验证插件
2014/01/31 Javascript
让jQuery Mobile不显示讨厌loading界面的方法
2014/02/19 Javascript
js常用数组操作方法简明总结
2014/06/20 Javascript
node.js中的fs.readlink方法使用说明
2014/12/17 Javascript
Javascript中拼接大量字符串的方法
2015/02/05 Javascript
jQuery实现冻结表格行和列
2015/04/29 Javascript
javascript实现的全国省市县无刷新多级关联菜单效果代码
2016/08/01 Javascript
jquery easyUI中ajax异步校验用户名
2016/08/19 Javascript
wap手机端解决返回上一页的js实例
2016/12/08 Javascript
Javascript计算二维数组重复值示例代码
2016/12/18 Javascript
微信小程序 动态的设置图片的高度和宽度详解及实例代码
2017/02/24 Javascript
js实现3D图片环展示效果
2017/03/09 Javascript
浅谈Vue2.0父子组件间事件派发机制
2018/01/08 Javascript
一些可能会用到的Node.js面试题
2019/06/15 Javascript
javascript触发模拟鼠标点击事件
2019/06/26 Javascript
JS实现点击发送验证码 xx秒后重新发送功能
2019/07/30 Javascript
layer ui插件显示tips时,修改字体颜色的实现方法
2019/09/11 Javascript
[48:23]DOTA2上海特级锦标赛主赛事日 - 4 败者组第四轮#1COL VS EG第一局
2016/03/05 DOTA
python 画条形图(柱状图)实例
2020/04/24 Python
世界上最好的足球商店:Unisport
2019/03/02 全球购物
自我鉴定怎么写
2013/12/05 职场文书
乡镇务虚会发言材料
2014/10/20 职场文书
土地租赁协议书
2015/01/29 职场文书
诚信考试承诺书范文
2015/04/29 职场文书
全国助残日活动总结
2015/05/11 职场文书
公文格式,规则明细(新手收藏)
2019/07/23 职场文书
制作能在nginx和IIS中使用的ssl证书
2021/06/21 Servers
MySQL创建定时任务
2022/01/22 MySQL