视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
React渲染列表的方法介绍(附代码)
2020-11-27 19:29:37 责编:小采
文档


本篇文章给大家带来的内容是关于React渲染列表的方法介绍(附代码),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。

对于一个展示页面来讲, 通常有好几种展示状态(以列表页为例):

数据为空, 空页面
取数据时发生错误, 错误页面
数据正常
加载状态
针对以上三种情况, 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>
 )
 }
}

其次我们可以把加载, 错误, 以及空状态统一抽成组件, 对于提高组件的复用率无疑可以起很大作用.

下载本文
显示全文
专题