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的扩展性也比较好,关于运用组件的开辟者来讲,也比较友爱。

    原文作者:nero
    原文地址: https://segmentfault.com/a/1190000019411474
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞