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温习篇 强大的JQuery选择器
Apr 24 Javascript
JQuery 拾色器插件发布-jquery.icolor.js
Oct 20 Javascript
Javascript图像处理—虚拟边缘介绍及使用方法
Dec 27 Javascript
jquery实现table鼠标经过变色代码
Sep 25 Javascript
Firefox和IE兼容性问题及解决方法总结
Oct 08 Javascript
JavaScript function 的 length 属性使用介绍
Sep 15 Javascript
jquery选择器需要注意的问题
Nov 26 Javascript
JS实现新浪博客左侧的Blog管理菜单效果代码
Oct 22 Javascript
JS与jQuery遍历Table所有单元格内容的方法
Dec 07 Javascript
详解JavaScript UTC时间转换方法
Jan 07 Javascript
js实现上传并压缩图片效果
Jan 10 Javascript
vue动态绑定class选中当前列表变色的方法示例
Dec 19 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个人网站架设连环讲(一)
2006/10/09 PHP
Bo-Blog专用的给Windows服务器的IIS Rewrite程序
2007/08/26 PHP
php中常量DIRECTORY_SEPARATOR用法深入分析
2014/11/14 PHP
thinkphp实现附件上传功能
2017/05/26 PHP
php实现的二叉树遍历算法示例
2017/06/15 PHP
PHP如何将图片文件上传到另外一台服务器上
2019/08/26 PHP
Javascript操纵Cookie实现购物车程序
2007/02/15 Javascript
var与Javascript变量隐式声明
2009/09/17 Javascript
使用Json比用string返回数据更友好,也更面向对象一些
2011/09/13 Javascript
查看图片(前进后退)功能实现js代码
2013/04/24 Javascript
javascript中的原型链深入理解
2014/02/24 Javascript
基于JavaScript实现生成名片、链接等二维码
2015/09/20 Javascript
深入探讨javascript函数式编程
2015/10/11 Javascript
jQuery使用模式窗口实现在主页面和子页面中互相传值的方法
2016/03/01 Javascript
详解vue-Resource(与后端数据交互)
2017/01/16 Javascript
详解Vue项目引入CreateJS的方法(亲测可用)
2019/05/30 Javascript
解决ele ui 表格表头太长问题的实现
2019/11/13 Javascript
微信小程序如何加载数据库真实数据的实现
2020/03/04 Javascript
[01:16]DOTA2小知识课堂 Ep.03 芒果树无伤肉山
2019/12/05 DOTA
[48:24]完美世界DOTA2联赛循环赛LBZS vs Forest 第一场 10月30日
2020/10/31 DOTA
[00:49]完美世界DOTA2联赛10月28日开团时刻:随便打
2020/10/29 DOTA
Python中的Numeric包和Numarray包使用教程
2015/04/13 Python
python安装mysql-python简明笔记(ubuntu环境)
2016/06/25 Python
Python实现Smtplib发送带有各种附件的邮件实例
2017/06/05 Python
python实现微信远程控制电脑
2018/02/22 Python
python3利用Axes3D库画3D模型图
2020/03/25 Python
Jupyter打开图形界面并画出正弦函数图像实例
2020/04/24 Python
django跳转页面传参的实现
2020/09/17 Python
全天然狗零食:Best Bully Sticks
2016/09/22 全球购物
超市中秋节促销方案
2014/03/21 职场文书
地质灾害防治方案
2014/05/14 职场文书
导师工作推荐信范文
2014/05/17 职场文书
计算机专业求职信
2014/06/02 职场文书
法人代表证明书
2014/09/18 职场文书
小学假期安全广播稿
2014/09/28 职场文书
bose降噪耳机音能消除人声吗
2022/04/19 数码科技