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 相关文章推荐
把textarea中字符串里含有的回车换行替换成&amp;lt;br&amp;gt;的javascript代码
Apr 20 Javascript
javascript中的作用域和上下文使用简要概述
Dec 05 Javascript
javascript实现锁定网页、密码解锁效果(类似系统屏幕保护效果)
Aug 15 Javascript
jQuery的context属性用法实例
Dec 27 Javascript
javascript实现获取浏览器版本、浏览器类型
Dec 02 Javascript
安装使用Mongoose配合Node.js操作MongoDB的基础教程
Mar 01 Javascript
谈一谈js中的执行环境及作用域
Mar 30 Javascript
Vue实例简单方法介绍
Jan 20 Javascript
jQuery实现动态添加、删除按钮及input输入框的方法
Apr 27 jQuery
vuejs 单文件组件.vue 文件的使用
Jul 28 Javascript
js原生map实现的方法总结
Jan 19 Javascript
小程序实现录音功能
Sep 22 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
一个用于MySQL的PHP XML类
2006/10/09 PHP
php上的memcache和memcached两个pecl库
2010/03/29 PHP
php数组函数序列 之array_count_values() 统计数组中所有值出现的次数函数
2011/10/29 PHP
PHP版微信公众平台红包API
2015/04/02 PHP
PHP实现即时输出、实时输出内容方法
2015/05/27 PHP
PHP自定义函数实现assign()数组分配到模板及extract()变量分配到模板功能示例
2018/05/23 PHP
JavaScript的setAttribute兼容性问题解决方法
2013/11/11 Javascript
jQuery动态改变图片显示大小(修改版)的实现思路及代码
2013/12/24 Javascript
nodejs中操作mysql数据库示例
2014/12/20 NodeJs
jQuery中queue()方法用法实例
2014/12/29 Javascript
微信小程序中input标签详解及简单实例
2017/05/18 Javascript
基于javaScript的this指向总结
2017/07/22 Javascript
es6学习之解构时应该注意的点
2017/08/29 Javascript
jquery自定义显示消息数量
2017/12/19 jQuery
详解Vue中watch的高级用法
2018/05/02 Javascript
浅谈Vue服务端渲染框架Nuxt的那些事
2018/12/21 Javascript
详解vue的数据劫持以及操作数组的坑
2019/04/18 Javascript
通过原生vue添加滚动加载更多功能
2019/11/21 Javascript
JS动态图片的实现方法完整示例
2020/01/13 Javascript
卸载vue2.0并升级vue_cli3.0的实例讲解
2020/02/16 Javascript
[02:05]2014DOTA2西雅图邀请赛 专访啸天mik夫妻档
2014/07/08 DOTA
[52:37]完美世界DOTA2联赛循环赛 Forest vs DM BO2第一场 10.29
2020/10/29 DOTA
Python列表(list)常用操作方法小结
2015/02/02 Python
Python自定义scrapy中间模块避免重复采集的方法
2015/04/07 Python
在cmd中运行.py文件: python的操作步骤
2018/05/12 Python
python 多进程共享全局变量之Manager()详解
2019/08/15 Python
基于python实现复制文件并重命名
2020/09/16 Python
如何利用python 读取配置文件
2021/01/06 Python
德国大型和小型家用电器网上商店:Energeto
2019/05/15 全球购物
韩国乐天网上商城:Lotte iMall
2021/02/03 全球购物
网上蛋糕店创业计划书
2014/01/24 职场文书
我的求职择业计划书
2014/04/04 职场文书
党的群众路线教育实践活动对照检查材料思想汇报(党员篇)
2014/09/25 职场文书
AJAX实现指定部分页面刷新效果
2021/10/16 Javascript
十大经典日本动漫排行榜 海贼王第三,犬夜叉仅第八
2022/03/18 日漫
CentOS下安装Jenkins的完整步骤
2022/04/07 Servers