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 相关文章推荐
获取服务器传来的数据 用JS去空格的正则表达式
Mar 26 Javascript
jQuery.buildFragment使用方法及思路分析
Jan 07 Javascript
AngularJs中Bootstrap3 datetimepicker使用实例
Dec 13 Javascript
jQuery 插件实现随机自由弹跳气泡样式
Jan 12 Javascript
IScroll那些事_当内容不足时下拉刷新的解决方法
Jul 18 Javascript
JScript实现表格的简单操作
Aug 15 Javascript
webpack打包js文件及部署的实现方法
Dec 18 Javascript
详解处理Vue单页面应用SEO的另一种思路
Nov 09 Javascript
layui富文本编辑器前端无法取值的解决方法
Sep 18 Javascript
Javascript地址引用代码实例解析
Feb 25 Javascript
JavaScript中layim之整合右键菜单的示例代码
Feb 06 Javascript
vue配置型表格基于el-table拓展之table-plus组件
Apr 12 Vue.js
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下使用curl模拟用户登陆的代码
2010/09/10 PHP
php长字符串定义方法
2012/07/12 PHP
WordPress中Gravatar头像缓存到本地及相关优化的技巧
2015/12/19 PHP
linux平台编译安装PHP7并安装Redis扩展与Swoole扩展实例教程
2016/09/30 PHP
利用php + Laravel如何实现部署自动化详解
2017/10/11 PHP
PHP实现的防止跨站和xss攻击代码【来自阿里云】
2018/01/29 PHP
有一段有意思的代码-javascript现实多行信息
2007/08/26 Javascript
jquery.AutoComplete.js中文修正版(支持firefox)
2010/04/09 Javascript
JS事件Event元素(兼容IE,Firefox,Chorme)
2012/11/01 Javascript
js,jquery滚动/跳转页面到指定位置的实现思路
2014/06/03 Javascript
Javascript URI 解析介绍
2015/03/15 Javascript
JS显示下拉列表框内全部元素的方法
2015/03/31 Javascript
浅谈js中几种实用的跨域方法原理详解
2016/12/02 Javascript
easyUI下拉列表点击事件使用方法
2017/05/18 Javascript
node.js遍历目录的方法示例
2018/08/01 Javascript
vue实现简单的MVVM框架
2018/08/05 Javascript
在Django的上下文中设置变量的方法
2015/07/20 Python
对Python 2.7 pandas 中的read_excel详解
2018/05/04 Python
浅谈Python接口对json串的处理方法
2018/12/19 Python
python+selenium实现自动化百度搜索关键词
2019/06/03 Python
详解在Python中以绝对路径或者相对路径导入文件的方法
2019/08/30 Python
Python操作SQLite数据库过程解析
2019/09/02 Python
Python利用逻辑回归分类实现模板
2020/02/15 Python
屏蔽Django admin界面添加按钮的操作
2020/03/11 Python
Python实现电视里的5毛特效实例代码详解
2020/05/15 Python
Amara德国:家居饰品、设计师品牌和豪华礼品
2019/05/20 全球购物
建筑实习自我鉴定
2013/10/18 职场文书
中药学自荐信
2014/06/15 职场文书
2014老师三严三实对照检查材料思想汇报
2014/09/18 职场文书
作风建设年活动实施方案
2014/10/24 职场文书
一般基层干部群众路线教育实践活动个人对照检查材料
2014/11/04 职场文书
2014年学生会主席工作总结
2014/11/07 职场文书
论文答辩开场白大全
2015/05/27 职场文书
2017年大学生寒假社会实践活动总结
2016/04/06 职场文书
CSS实现渐变色边框(Gradient borders)的5种方法
2022/03/25 HTML / CSS
JS实现刷新网页后之前浏览位置保持不变示例详解
2022/08/14 Javascript