资讯专栏INFORMATION COLUMN

React组件设计模式-组合组件

Jonathan Shieber / 2306人阅读

摘要:组件有两个关键的表明当前是否应高亮,自己被点击时调用的回调函数,由于是每个页面的容器,它只负责把渲染出来,所以用函数式组件即可。

这种模式本质上解决的是组件之间传值的问题。但是它对于传值以及一些内部操控的逻辑封装得更严密。

场景:希望减少上下级组件之间props的传递,简单来说就是不用传做显式地传值,来达到组件之间相互通信的目的

举例来说,某些界面中应该有Tabs这样的组件,由Tab和TabItem组成,点击每个TabItem,该TabItem会高亮,
那么Tab和TabItem自然要进行沟通。很自然的写法是像下面这样

One
Two
Three

这样的缺点很明显:

每次使用 TabItem 都要传递一堆 props

每增加一个新的 TabItem,都要增加对应的 props

如果要增加 TabItem,就要去修改 Tabs 的 JSX 代码

但是,组件之间的交互我们又不希望通过props或者context来实现。希望用法如下面一样简洁。

    
      第一
      第二
      第三
    

组件之间通过隐秘的方式进行通信,但这里的隐秘实际上是对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 <>
    

{children}

}

我们再来回顾一下想到达到的效果:

    
      第一
      第二
      第三
    

使用组件时要避免传递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 
{newChildren}
} }

这里需要用到React不常用的api:

React.Children.map

React.cloneElement

使用React.Children.map来对props.children进行遍历。

React.cloneElement可以复制某个元素,第一个参数是被复制的元素,第二个参数我们可以把想传入的props加进去,也就是这个时机,
我们将active和onTabClick传入。实现最终效果。

总结

这种模式比较好的把复杂逻辑完全封装起来了,抽象程度更好,比较适合开发组件开发者。针对props的扩展性也比较好,对于使用组件的开发者来说,也比较友好。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/104503.html

相关文章

  • 可靠React组件设计的7个准则之组合和复用

    摘要:幸运的是,组合易于理解。组件的组合是自然而然的。高效用户界面可组合的层次结构,因此,组件的组合是一种构建用户界面的有效的方式。这个原则建议避免重复。只有一个组件符合单一责任原则并且具有合理的封装时,它是可复用的。 翻译:刘小夕原文链接:https://dmitripavlutin.com/7-... 原文的篇幅非常长,不过内容太过于吸引我,还是忍不住要翻译出来。此篇文章对编写可重用和...

    Amos 评论0 收藏0
  • 精益 React 学习指南 (Lean React)- 1.1 React 介绍

    摘要:单向数据流应用的核心设计模式,数据流向自顶向下我也是性子急的人,按照技术界的惯例,在学习一个技术前,首先得说一句。然而的单向数据流的设计让前端定位变得简单,页面的和数据的对应是唯一的我们可以通过定位数据变化就可以定位页面展现问题。 书籍完整目录 1.1 React 介绍 showImg(https://segmentfault.com/img/bVvJgS); 1.1.1 React ...

    lsxiao 评论0 收藏0
  • 少妇白洁系列之React StateUp模式

    摘要:一般这种情况会在类的构造函数内创建一个属性,引用或词法域的,但后面会看到我们有更好的办法,避免这种手工代码。 换句话说,StateUp模式把面向对象的设计方法应用到了状态对象的管理上,在遵循React的组件化机制和基于props实现组件通讯方式的前提之下做到了这一点。 ---- 少妇白洁 阅读本文之前,请确定你读过React的官方文档中关于Lifting State Up的论述: ht...

    jaysun 评论0 收藏0
  • React中的函数子组件(FaCC)和高阶组件(HOC)

    摘要:高阶函数我们都用过,就是接受一个函数然后返回一个经过封装的函数而高阶组件就是高阶函数的概念应用到高阶组件上使用接受一个组件返回一个经过包装的新组件。灵活性在组合阶段相对更为灵活,他并不规定被增强组件如何使用它传递下去的属性。 在接触过React项目后,大多数人都应该已经了解过或则用过了HOC(High-Order-Components)和FaCC(Functions as Child ...

    elliott_hu 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<