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>
    
    
    コンポーネントを使う時にプロの欠点を伝えないといけませんが、どこで伝達しますか?もちろんTabsコンポーネントです。でも、上記はpropsに入っていません。
    Tabsはpropsの中のchildrenにアクセスできますが、手に入れたchildrenはすでに既成のものです。直せば問題が発生します。
    チルドレンを直接変えてはいけないなら、チルドレンを一つコピーして、これを変えてコピーしたチルドレンをレンダリングしたらいいです。
    次に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を伝えます。最終効果を実現する。
    締め括りをつける
    このようなモードは複雑な論理を完全にカプセル化したほうがいいです。抽象度がもっといいです。コンポーネント開発者に向いています。プロに対しても拡張性が高く、コンポーネントを使う開発者にとっても友好的です。
    本論文で述べたように、皆さんのreactプログラムの設計に役に立ちます。