欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

React组件设计模式之组合组件应用实例分析

程序员文章站 2023-11-09 13:40:58
本文实例讲述了react组件设计模式之组合组件应用。分享给大家供大家参考,具体如下:这种模式本质上解决的是组件之间传值的问题。但是它对于传值以及一些内部操控的逻辑封装得更严密。场景:希望减少上下级组件...

本文实例讲述了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程序设计有所帮助。