React组件设计模式之组合组件应用实例分析


Posted in Javascript onApril 29, 2020

本文实例讲述了React组件设计模式之组合组件应用。分享给大家供大家参考,具体如下:

这种模式本质上解决的是组件之间传值的问题。但是它对于传值以及一些内部操控的逻辑封装得更严密。

场景:希望减少上下级组件之间props的传递,简单来说就是不用传做显式地传值,来达到组件之间相互通信的目的

举例来说,某些界面中应该有Tabs这样的组件,由Tab和TabItem组成,点击每个TabItem,该TabItem会高亮,

那么Tab和TabItem自然要进行沟通。很自然的写法是像下面这样

<TabItem active={true} onClick={this.onClick}>One</TabItem>
<TabItem active={false} onClick={this.onClick}>Two</TabItem>
<TabItem active={false} onClick={this.onClick}>Three</TabItem>

这样的缺点很明显:

  • 每次使用 TabItem 都要传递一堆 props
  • 每增加一个新的 TabItem,都要增加对应的 props
  • 如果要增加 TabItem,就要去修改 Tabs 的 JSX 代码

但是,组件之间的交互我们又不希望通过props或者context来实现。希望用法如下面一样简洁。

<Tabs>
   <TabItem>第一</TabItem>
   <TabItem>第二</TabItem>
   <TabItem>第三</TabItem>
  </Tabs>

组件之间通过隐秘的方式进行通信,但这里的隐秘实际上是对props的操作在一个地方进行管理。

实现

明白了要实现的交互,和代码层面要实现的效果,就可以开始动手了。

TabItem组件有两个关键的props: active(表明当前是否应高亮),onTabClick(自己被点击时调用的回调函数),

TabItem由于是每个Tab页面的容器,它只负责把props.children渲染出来,所以用函数式组件即可。

export const TabItem = props => {
 const { active, onTabClick, children } = props
 const style = {
  color: active ? 'red' : 'green',
  cursor: 'pointer'
 }
 return <>
  <h1 style={style} onClick={onTabClick}>
   {children}
  </h1>
 </>
}

我们再来回顾一下想到达到的效果:

<Tabs>
   <TabItem>第一</TabItem>
   <TabItem>第二</TabItem>
   <TabItem>第三</TabItem>
  </Tabs>

使用组件时要避免传递props的缺点,那么在哪里传递呢?自然是是Tabs组件。但上面并没有传入props啊。

Tabs 虽然可以访问到props里边的children,但是到手的children已经是现成的如果直接改它的话,会出问题。

不可以直接改children的话,我们就把children复制一份,然后改这个复制过来的children,再渲染出去,就ok啦!

下面来看Tabs的实现:

class Tabs extends React.Component {
 state={
  activeIndex: 0
 }
 render() {
  const { activeIndex } = this.state
  const newChildren = React.Children.map(this.props.children, (child, index) => {
   if (child.type) {
     // 复制并修改children
    return React.cloneElement(child, {
     active: activeIndex === index,
     onTabClick: () => this.setState({activeIndex: index})
    })
   } else {
    return child
   }
  })
  return <div className="tabs">
   {newChildren}
  </div>
 }
}

这里需要用到React不常用的api:

  • React.Children.map
  • React.cloneElement

使用React.Children.map来对props.children进行遍历。

React.cloneElement可以复制某个元素,第一个参数是被复制的元素,第二个参数我们可以把想传入的props加进去,也就是这个时机,

我们将active和onTabClick传入。实现最终效果。

总结

这种模式比较好的把复杂逻辑完全封装起来了,抽象程度更好,比较适合开发组件开发者。针对props的扩展性也比较好,对于使用组件的开发者来说,也比较友好。

希望本文所述对大家react程序设计有所帮助。

Javascript 相关文章推荐
jquery(live)中File input的change方法只起一次作用的解决办法
Oct 21 Javascript
js修改input的type属性及浏览器兼容问题探讨与解决
Jan 23 Javascript
如何在JavaScript中实现私有属性的写类方式(二)
Dec 04 Javascript
一个小例子解释如何来阻止Jquery事件冒泡
Jul 17 Javascript
超级简单的jquery操作表格方法
Dec 15 Javascript
JavaScript数据类型之基本类型和引用类型的值
Apr 01 Javascript
ionic由于使用了header和subheader导致被遮挡的问题的两种解决方法
Sep 22 Javascript
bootstrap实现动态进度条效果
Mar 08 Javascript
解决webpack -p压缩打包react报语法错误的方法
Jul 03 Javascript
JavaScript常见继承模式实例小结
Jan 11 Javascript
JavaScript 正则应用详解【模式、欲查、反向引用等】
May 13 Javascript
js实现从右往左匀速显示图片(无缝轮播)
Jun 29 Javascript
Vue + Node.js + MongoDB图片上传组件实现图片预览和删除功能详解
Apr 29 #Javascript
JS数组push、unshift、pop、shift方法的实现与使用方法示例
Apr 29 #Javascript
JS实现手写 forEach算法示例
Apr 29 #Javascript
Node.js API详解之 querystring用法实例分析
Apr 29 #Javascript
Node.js API详解之 string_decoder用法实例分析
Apr 29 #Javascript
深入浅析vue全局环境变量和模式
Apr 28 #Javascript
你准备好迎接vue3.0了吗
Apr 28 #Javascript
You might like
一个PHP针对数字的加密解密类
2014/03/20 PHP
Yii框架批量插入数据扩展类的简单实现方法
2017/05/23 PHP
JavaScript Event学习第二章 Event浏览器兼容性
2010/02/07 Javascript
网页编辑器ckeditor和ckfinder配置步骤分享
2012/05/24 Javascript
JavaScript 在网页上单击鼠标的地方显示层及关闭层
2012/12/30 Javascript
js函数排序的实例代码
2013/07/01 Javascript
js动态修改input输入框的type属性(实现方法解析)
2013/11/13 Javascript
将中国标准时间转换成标准格式的代码
2014/03/20 Javascript
Jquery设置attr的disabled属性控制某行显示或者隐藏
2014/09/25 Javascript
javascript学习笔记(二)数组和对象部分
2014/09/30 Javascript
基于jQuery实现多层次的手风琴效果附源码
2015/09/21 Javascript
Bootstrap基本模板的使用和理解1
2016/12/14 Javascript
JS 仿支付宝input文本输入框放大组件的实例
2017/11/14 Javascript
JS中的回调函数实例浅析
2018/03/21 Javascript
浅谈从React渲染流程分析Diff算法
2018/09/08 Javascript
在axios中使用params传参的时候传入数组的方法
2018/09/25 Javascript
npm scripts 使用指南详解
2018/10/08 Javascript
webpack开发环境和生产环境的深入理解
2018/11/08 Javascript
详解javascript void(0)
2020/07/13 Javascript
使用JavaScript实现贪吃蛇游戏
2020/09/29 Javascript
Python制作爬虫抓取美女图
2016/01/20 Python
Python脚本实现虾米网签到功能
2016/04/12 Python
下载python中Crypto库报错:ModuleNotFoundError: No module named ‘Crypto’的解决
2018/04/23 Python
python实现任意位置文件分割的实例
2018/12/14 Python
Python常见数据结构之栈与队列用法示例
2019/01/14 Python
Python爬取视频(其实是一篇福利)过程解析
2019/08/01 Python
Python 3.8正式发布,来尝鲜这些新特性吧
2019/10/15 Python
使用python制作一个解压缩软件
2019/11/13 Python
python3实现在二叉树中找出和为某一值的所有路径(推荐)
2019/12/26 Python
Ubuntu18.04安装 PyCharm并使用 Anaconda 管理的Python环境
2020/04/08 Python
使用darknet框架的imagenet数据分类预训练操作
2020/07/07 Python
AC Lens:购买隐形眼镜
2017/02/26 全球购物
家具商场的活动方案
2014/08/16 职场文书
教师自我剖析材料范文
2014/09/30 职场文书
文案策划岗位职责
2015/02/11 职场文书
关于EntityWrapper的in用法
2022/03/22 Java/Android