Reactコンポーネント設計モード-コンポーネントの組合せ
2884 ワード
このモードは本質的にコンポーネント間の値伝達の問題を解決する.しかし、伝達値や内部操作の論理はより厳密にカプセル化されています.
シーン:上下のコンポーネント間のpropsの伝達を減らすには,簡単に言えば明示的に値を伝達することなく,コンポーネント間の相互通信の目的を達成することである.
たとえば、一部のインタフェースにはTabsのようなコンポーネントがあり、TabとTabItemから構成され、各TabItemをクリックすると、TabItemがハイライトされ、TabとTabItemは自然にコミュニケーションを取らなければならない.自然な書き方は次のようになります
このような欠点は明らかです. TabItemを使用するたびにprops を渡す新しいTabItemを追加するたびに、対応するprops を追加します. TabItemを追加する場合は、TabsのJSXコード を変更します.
しかし、コンポーネント間のインタラクションはpropsやcontextで実現することを望んでいません.使い方は以下のように簡潔にしてほしい.
コンポーネント間では秘密裏に通信が行われるが,ここでの秘密は実際にはpropsの操作を1つの場所で管理する.
実現するインタラクションと,コードレベルで実現する効果を理解すれば,着手できる.
TabItemコンポーネントには2つの重要なpropsがある:active(現在ハイライトすべきかどうかを示す)、onTabClick(自分がクリックされたときに呼び出されたコールバック関数)、TabItemはTabページごとのコンテナであるため、propsのみを担当する.childrenがレンダリングされるので、関数コンポーネントでいいです.
達成した効果を振り返ってみましょう.
コンポーネントを使用するときにpropsを渡す欠点を避けるには、どこで渡すのでしょうか.もちろんTabsコンポーネントです.しかし、propsは伝わっていませんね.Tabsはpropsの中のchildrenにアクセスできますが、手に入れたchildrenはすでに既製で直接変更すると問題になります.直接childrenを変更できない場合は、childrenをコピーして、このコピーしたchildrenを変更して、レンダリングして、okになります!
次に、Tabsの実装について説明する.
ここではReactではあまり使われていないapiを使用する必要があります. React.Children.map React.cloneElement
このモデルは複雑な論理を完全にカプセル化し,抽象度がより良く,コンポーネント開発者に適している.propsの拡張性にも優れており,コンポーネントを使用する開発者にとっても友好的である.
シーン:上下のコンポーネント間のpropsの伝達を減らすには,簡単に言えば明示的に値を伝達することなく,コンポーネント間の相互通信の目的を達成することである.
たとえば、一部のインタフェースにはTabsのようなコンポーネントがあり、TabとTabItemから構成され、各TabItemをクリックすると、TabItemがハイライトされ、TabとTabItemは自然にコミュニケーションを取らなければならない.自然な書き方は次のようになります
One
Two
Three
このような欠点は明らかです.
しかし、コンポーネント間のインタラクションは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
を用いるprops.childrenが遍歴する.React.cloneElement
はある要素をコピーすることができて、第1のパラメータはコピーされた要素で、第2のパラメータは私たちが入力したいpropsを加えることができて、つまりこのタイミングで、私たちはactiveとonTabClickを入力します.最終的な効果を実現します.まとめ
このモデルは複雑な論理を完全にカプセル化し,抽象度がより良く,コンポーネント開発者に適している.propsの拡張性にも優れており,コンポーネントを使用する開発者にとっても友好的である.