いつReact.cloneElementとthis.props.childrenを使用する必要がありますか?


118

私はまだReactの初心者であり、インターネット上の多くの例では、子要素のレンダリングにこのバリエーションがあり、混乱しています。通常私はこれを見ます:

class Users extends React.Component {
  render() {
    return (
      <div>
        <h2>Users</h2>
        {this.props.children}
      </div>
    )
  }
}

しかし、それから私はこのような例を見ます:

<ReactCSSTransitionGroup
     component="div"
     transitionName="example"
     transitionEnterTimeout={500}
     transitionLeaveTimeout={500}
     >
     {React.cloneElement(this.props.children, {
       key: this.props.location.pathname
      })}
</ReactCSSTransitionGroup>

今私はAPIを理解していますが、ドキュメントは私がそれをいつ使用すべきかを明確に示していません。

では、他の人ができないことは、何をするのでしょうか?誰かがこれをより良い例で私に説明できますか?


3
youtube.com/watch?v=hEGg-3pIHlEこの男は、cloneElementの使い方を示しています。いくつかの例については、こちらを
ご覧

回答:


69

編集:

代わりにVennesaの答えを見てください。これはより良い説明です。

元の:

まず、このReact.cloneElement例は、子供が単一のReact要素である場合にのみ機能します。

ほとんどすべてのために{this.props.children}あなたが欲しいものです。複製は、親が要素を送信し、子コンポーネントがその要素のいくつかの小道具を変更するか、実際のDOM要素にアクセスするためのrefなどを追加する必要がある、より高度なシナリオで役立ちます。

上記の例では、子を与える親はコンポーネントのキー要件を知らないため、与えられた要素のコピーを作成し、オブジェクト内の一意の識別子に基づいてキーを追加します。キーの機能の詳細:https : //facebook.github.io/react/docs/multiple-components.html


183

props.children実際の子供ではありません。それはdescriptor子供たちの。したがって、実際に変更する必要はありません。小道具を変更したり、機能を編集したりすることはできません。あなただけができますread from it。変更を加える必要がある場合は、をnew elements使用して作成する必要がありますReact.CloneElement

https://egghead.io/lessons/react-use-react-cloneelement-to-extend-functionality-of-children-components

例:

次のようなコンポーネントの主なレンダリング機能App.js

render() {   
    return(
            <Paragraph>
              <Sentence>First</Sentence>
              <Sentence>Second</Sentence>
              <Sentence>Third</Sentence>
            </Paragraph>   
    ) 
}

onClick各子にを追加する必要があるとしましょうParagraph。あなたの中にこれParagraph.jsを行うことができます。

render() {
        return (
          <div>
          {React.Children.map(this.props.children, child => {
            return React.cloneElement(child, {
              onClick: this.props.onClick })   
         })}
         </div>
       ) 
}

その後、単にこれを行うことができます:

render() {   
  return(
        <Paragraph onClick={this.onClick}>
          <Sentence>First</Sentence>
          <Sentence>Second</Sentence>
          <Sentence>Third</Sentence>
        </Paragraph>   
   ) 
}

注:React.Children.mapこの関数はのみ表示されますtop level、それはこれらの要素をレンダリングすること、物事のいずれかを見ていない、要素を。つまり、子供(ここでは<Sentence />要素)に直接小道具を提供しています。小道具をさらに受け渡す必要がある場合は、小道具を使用したい要素の<div></div>1つが内部に<Sentence />あるとします。onClickその場合は、を使用Context APIしてそれを実行できます。作りParagraphプロバイダやSentence消費者などの要素を。


11
これは、実例を用いた明確な答えです。より多くの賛成票が必要です。
SeaWarrior404 2018

1
@ SeaWarrior404に同意する-彼のユーザーインターフェイスのタイトルが "Users" / pluralであるため、OPは単一の子ではなくコレクションを反復処理することを検討していたと思います。@vennesaが指摘するように、React.Children.mapと組み合わせて使用するReact.cloneElementことは非常に強力です
jakeforaker

23

実際、React.cloneElementはに厳密に関連付けられていませんthis.props.children

PropTypes.element親がそれらのコンポーネントの内部についての知識を持たなくても(たとえば、イベントハンドラーのアタッチやkey/ ref属性の割り当て)、反応要素()を複製して小道具をオーバーライドする必要がある場合に便利です。

反応要素も不変です。

React.cloneElement(element、[props]、[... children])は、ほぼ以下と同等です: <element.type {...element.props} {...props}>{children}</element.type>


ただし、childrenReact のプロップは特に包含(別名合成)に使用され、React.ChildrenAPIとペアになっておりReact.cloneElement、props.childrenを使用するコンポーネントは内部でより多くのロジック(状態遷移、イベント、DOM測定など)を処理しながらレンダリングパーツを生成できます。どこで使用されても、React Router <switch/>や複合コンポーネント<select/>はいくつかの素晴らしい例です。

言及する価値がある最後の1つは、react要素がprops.childrenに制限されていないことです。

function SplitPane(props) {
  return (
    <div className="SplitPane">
      <div className="SplitPane-left">
        {props.left}
      </div>
      <div className="SplitPane-right">
        {props.right}
      </div>
    </div>
  );
}

function App() {
  return (
    <SplitPane
      left={
        <Contacts />
      }
      right={
        <Chat />
      } />
  );
}

彼らは理にかなっているものは何でも小道具することができ、キーは、コンポーネントの良い契約を定義することでしたので、それの消費者はそれを使っているかどうかにかかわらず、基礎となる実装の詳細から切り離すことができることをReact.ChildrenReact.cloneElementまたはさえReact.createContext

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.