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 相关文章推荐
jquery1.5.1中根据元素ID获取元素对象的代码
Apr 02 Javascript
jQuery中获取Radio元素值的方法
Jul 02 Javascript
JQuery1.8 判断元素是否绑定事件的方法
Jul 10 Javascript
javascript消除window.close()的提示窗口
May 20 Javascript
JavaScript中的定时器之Item23的合理使用
Oct 30 Javascript
微信小程序 wxapp地图 map详解
Oct 31 Javascript
如何使用Bootstrap 按钮实例详解
Mar 29 Javascript
详解webpack 入门总结和实践(按需异步加载,css单独打包,生成多个入口文件)
Jun 20 Javascript
Angular4实现鼠标悬停3d倾斜效果
Oct 25 Javascript
浅谈webpack 构建性能优化策略小结
Jun 13 Javascript
新手入门带你学习JavaScript引擎运行原理
Jun 24 Javascript
JavaScript图像放大镜效果实现方法详解
Jun 28 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
Drupal7中常用的数据库操作实例
2014/03/02 PHP
利用phpexcel对数据库数据的导入excel(excel筛选)、导出excel
2017/04/27 PHP
javascript 星级评分效果(手写)
2012/12/24 Javascript
JavaScript使用HTML5的window.postMessage实现跨域通信例子
2014/04/11 Javascript
JS 在指定数组中随机取出N个不重复的数据
2014/06/10 Javascript
分享我的jquery实现下拉菜单心的
2015/11/29 Javascript
两种方法解决javascript url post 特殊字符转义 + &amp; #
2016/04/13 Javascript
AngularJS 打开新的标签页实现代码
2017/09/07 Javascript
JS简单实现点击跳转登陆邮箱功能的方法
2017/10/31 Javascript
Angular8基础应用之表单及其验证
2019/08/11 Javascript
JavaScript实现猜数字游戏
2020/05/20 Javascript
基于canvasJS在PHP中制作动态图表
2020/05/30 Javascript
js实现纯前端压缩图片
2020/11/16 Javascript
[47:06]DOTA2上海特级锦标赛主赛事日 - 4 败者组第五轮 MVP.Phx VS EG第一局
2016/03/05 DOTA
python操作摄像头截图实现远程监控的例子
2014/03/25 Python
Python实现改变与矩形橡胶的线条的颜色代码示例
2018/01/05 Python
利用Pandas读取文件路径或文件名称包含中文的csv文件方法
2018/07/04 Python
Django JWT Token RestfulAPI用户认证详解
2019/01/23 Python
Python Django实现layui风格+django分页功能的例子
2019/08/29 Python
python的命名规则知识点总结
2019/10/04 Python
使用python代码进行身份证号校验的实现示例
2019/11/21 Python
python小项目之五子棋游戏
2019/12/26 Python
Pytorch提取模型特征向量保存至csv的例子
2020/01/03 Python
flask框架蓝图和子域名配置详解
2020/01/25 Python
使用OpenCV实现道路车辆计数的使用方法
2020/07/15 Python
简单介绍CSS3中Media Query的使用
2015/07/07 HTML / CSS
英语专业学子个人的自我评价
2013/10/02 职场文书
最新自我评价范文
2013/11/16 职场文书
校庆活动方案
2014/03/31 职场文书
公安机关查摆剖析材料
2014/10/10 职场文书
三方协议书
2015/01/27 职场文书
2015年审计人员工作总结
2015/05/26 职场文书
Vue实现导入Excel功能步骤详解
2021/07/03 Vue.js
java设计模式--七大原则详解
2021/07/21 Java/Android
MySQL 开窗函数
2022/02/15 MySQL
apache虚拟主机配置的三种方式(小结)
2022/07/23 Servers