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 相关文章推荐
一个网马的tips实现分析
Nov 28 Javascript
js单例模式的两种方案
Oct 22 Javascript
jQuery创建DOM元素实例解析
Jan 19 Javascript
JavaScript判断数组重复内容的两种方法(推荐)
Jun 06 Javascript
jQuery实现鼠标滚动图片延迟加载效果附源码下载
Jun 28 Javascript
IE下JS保存图片的简单实例
Jul 15 Javascript
JavaScript交换两个变量值的七种解决方案
Dec 01 Javascript
BootstrapValidator超详细教程(推荐)
Dec 07 Javascript
Bootstrap 中data-[*] 属性的整理
Mar 13 Javascript
在vue中使用echarts图表实例代码详解
Oct 22 Javascript
js canvas实现写字动画效果
Nov 30 Javascript
js prototype和__proto__的关系是什么
Aug 23 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
项目中应用Redis+Php的场景
2016/05/22 PHP
Extjs中的GridPanel隐藏列会显示在menuDisabled中解决方法
2013/01/27 Javascript
如何通过javascript操作web控件的自定义属性
2013/11/25 Javascript
jQuery 顶部导航跟随滚动条滚动固定浮动在顶部
2014/06/06 Javascript
JS对象与json字符串格式转换实例
2014/10/28 Javascript
javascript属性访问表达式用法分析
2015/04/25 Javascript
JavaScript中用toString()方法返回时间为字符串
2015/06/12 Javascript
JavaScript实现数据类型的相互转换
2016/03/06 Javascript
从零学习node.js之文件操作(三)
2017/02/21 Javascript
vue省市区三联动下拉选择组件的实现
2017/04/28 Javascript
vue.js $refs和$emit 父子组件交互的方法
2017/12/20 Javascript
解决vue打包之后静态资源图片失效的问题
2018/02/21 Javascript
layui表格checkbox选择全选样式及功能的实例
2018/03/07 Javascript
在 Typescript 中使用可被复用的 Vue Mixin功能
2018/04/17 Javascript
深入理解Vue 组件之间传值
2018/08/16 Javascript
jQuery ajax仿Google自动提示SearchSuggess功能示例
2019/03/28 jQuery
jQuery分组选择器简单用法示例
2019/04/04 jQuery
在MAC上搭建python数据分析开发环境
2016/01/26 Python
python实现远程通过网络邮件控制计算机重启或关机
2018/02/22 Python
利用Python yagmail三行代码实现发送邮件
2018/05/11 Python
Python2和Python3.6环境解决共存问题
2018/11/09 Python
Python装饰器原理与基本用法分析
2020/01/07 Python
Python实现井字棋小游戏
2020/03/09 Python
python实现取余操作的简单实例
2020/08/16 Python
CSS3 3D位移translate效果实例介绍
2016/05/03 HTML / CSS
iRobot官网:改变生活的家用机器人品牌
2016/09/20 全球购物
Linux Interview Questions For software testers
2012/06/02 面试题
环境工程大学生自荐信
2013/10/21 职场文书
六十岁生日答谢词
2014/01/10 职场文书
试用期转正鉴定评语
2014/01/27 职场文书
《猴子种果树》教学反思
2014/04/26 职场文书
产品质量保证书
2014/04/29 职场文书
公司副总经理岗位职责
2014/10/01 职场文书
离婚协议书范本2014
2014/10/27 职场文书
保险公司客户经理岗位职责
2015/04/09 职场文书
pytorch中[..., 0]的用法说明
2021/05/20 Python