Reactコンポーネント設計モード-コンポーネントの組合せ


このモードは本質的にコンポーネント間の値伝達の問題を解決する.しかし、伝達値や内部操作の論理はより厳密にカプセル化されています.
シーン:上下のコンポーネント間のpropsの伝達を減らすには,簡単に言えば明示的に値を伝達することなく,コンポーネント間の相互通信の目的を達成することである.
たとえば、一部のインタフェースにはTabsのようなコンポーネントがあり、TabとTabItemから構成され、各TabItemをクリックすると、TabItemがハイライトされ、TabとTabItemは自然にコミュニケーションを取らなければならない.自然な書き方は次のようになります
One
Two
Three

このような欠点は明らかです.
  • TabItemを使用するたびにprops
  • を渡す
  • 新しいTabItemを追加するたびに、対応するprops
  • を追加します.
  • TabItemを追加する場合は、TabsのJSXコード
  • を変更します.
    しかし、コンポーネント間のインタラクションはpropsやcontextで実現することを望んでいません.使い方は以下のように簡潔にしてほしい.
        
            
            
            
        

    コンポーネント間では秘密裏に通信が行われるが,ここでの秘密は実際にはpropsの操作を1つの場所で管理する.

    インプリメンテーション


    実現するインタラクションと,コードレベルで実現する効果を理解すれば,着手できる.
    TabItemコンポーネントには2つの重要な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はある要素をコピーすることができて、第1のパラメータはコピーされた要素で、第2のパラメータは私たちが入力したいpropsを加えることができて、つまりこのタイミングで、私たちはactiveとonTabClickを入力します.最終的な効果を実現します.

    まとめ


    このモデルは複雑な論理を完全にカプセル化し,抽象度がより良く,コンポーネント開発者に適している.propsの拡張性にも優れており,コンポーネントを使用する開発者にとっても友好的である.