React component design model - combination of components

React assembly design pattern -Provider-Consumer

React assembly design pattern -Render-props

This model is essentially solved the problem of traditional values ​​between components. Value, and pass it to a number of internal control logic package more closely.

Scene: props desirable to reduce the transmission assembly between the upper and lower levels, it simply is not passed explicitly to do traditional values, to achieve mutual communication between the components

For example, there should be some interface components such Tabs, Tab and TabItem by the composition, click on each TabItem, the TabItem is highlighted, and then the Tab TabItem naturally communicate. Naturally wording is as follows

<TabItem active={true} onClick={this.onClick}>One</TabItem>
<TabItem active={false} onClick={this.onClick}>Two</TabItem>
<TabItem active={false} onClick={this.onClick}>Three</TabItem>
复制代码

Such shortcomings are obvious:

  • TabItem each use must pass a bunch of props
  • Each additional new TabItem, will also increase the corresponding props
  • If you want to increase TabItem, JSX going to modify the code of Tabs

However, the interaction between the components that we do not want to achieve through props or context. I want to use as simple as below.

    <Tabs>
      <TabItem>第一</TabItem>
      <TabItem>第二</TabItem>
      <TabItem>第三</TabItem>
    </Tabs>
复制代码

Between components communicate by way of secret, but is in fact the secret operation props be managed from one place.


achieve

Understand the effect of interaction, and code level to be implemented to achieve, you can begin to hands.

TabItem component has two key props: active (indicate whether the current should be highlighted), onTabClick (own call a callback function when clicked), TabItem because it is a container for each Tab page, it is only responsible to render props.children , it can be a functional component.

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>
  </>
}

复制代码

We again look expect to achieve results:

    <Tabs>
      <TabItem>第一</TabItem>
      <TabItem>第二</TabItem>
      <TabItem>第三</TabItem>
    </Tabs>
复制代码

When a component to avoid passing the shortcomings of props, then you can transfer it? Yes Tabs natural components. But above and no incoming props ah. Tabs Although access to children props inside, but the hand of the children already are ready to change if it directly, it will go wrong. Can not directly change the children, we put the children a copy, and then change the copied children, then render out to ok it!

Tabs look at the following realization:

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>
  }
}
复制代码

It should not be used React common api:

  • React.Children.map
  • React.cloneElement

Use React.Children.mapto traverse to props.children.

And React.cloneElementyou can copy an element, the first argument is copied elements, the second argument we can think incoming props added, is this opportunity, we will be active and onTabClick passed. To achieve the final effect.

to sum up

This model better the complex logic package up, better level of abstraction, more suitable developer component developer. For the expansion of props is also better for developers to use components, it is also more friendly.

Reproduced in: https: //juejin.im/post/5cf8e153e51d4576bc1a0dc7

Guess you like

Origin blog.csdn.net/weixin_34396103/article/details/91434767