小道具を{this.props.children}に渡す方法


889

一般的な方法で使用できるいくつかのコンポーネントを定義する適切な方法を見つけようとしています:

<Parent>
  <Child value="1">
  <Child value="2">
</Parent>

もちろん、親と子のコンポーネント間のレンダリングのために行くの論理があり、あなたが想像できる<select><option>、このロジックの例としては。

これは質問のためのダミー実装です:

var Parent = React.createClass({
  doSomething: function(value) {
  },
  render: function() {
    return (<div>{this.props.children}</div>);
  }
});

var Child = React.createClass({
  onClick: function() {
    this.props.doSomething(this.props.value); // doSomething is undefined
  },
  render: function() {
    return (<div onClick={this.onClick}></div>);
  }
});

問題は{this.props.children}、ラッパーコンポーネントを定義するために使用するときはいつでも、すべての子にいくつかのプロパティをどのように渡すのですか?


回答:


955

新しい小道具で子供をクローンする

React.Childrenを使用して子を反復処理し、React.cloneElementを使用して各要素を新しい小道具(浅いマージ)で複製できます。例:

import React, { Children, isValidElement, cloneElement } from 'react';

const Child = ({ doSomething, value }) => (
  <div onClick={() => doSomething(value)}>Click Me</div>
);

function Parent({ children }) {
  function doSomething(value) {
    console.log('doSomething called by child with value:', value);
  }

  render() {
    const childrenWithProps = Children.map(children, child => {
      // Checking isValidElement is the safe way and avoids a TS error too.
      if (isValidElement(child)) {
        return cloneElement(child, { doSomething })
      }

      return child;
    });

    return <div>{childrenWithProps}</div>
  }
};

ReactDOM.render(
  <Parent>
    <Child value="1" />
    <Child value="2" />
  </Parent>,
  document.getElementById('container')
);

フィドル:https : //jsfiddle.net/2q294y43/2/

子を関数として呼び出す

レンダープロップ使用して、子供にプロップを渡すこともできます。このアプローチでは、子(childrenまたはその他のプロップ名)は、渡す引数を受け入れて子を返す関数です。

const Child = ({ doSomething, value }) => (
  <div onClick={() =>  doSomething(value)}>Click Me</div>
);

function Parent({ children }) {
  function doSomething(value) {
    console.log('doSomething called by child with value:', value);
  }

  render() {
    // Note that children is called as a function and we can pass args to it
    return <div>{children(doSomething)}</div>
  }
};

ReactDOM.render(
  <Parent>
    {doSomething => (
      <React.Fragment>
        <Child doSomething={doSomething} value="1" />
        <Child doSomething={doSomething} value="2" />
      </React.Fragment>
    )}
  </Parent>,
  document.getElementById('container')
);

代わりに、<React.Fragment>または単に、<>必要に応じて配列を返すこともできます。

フィドル:https : //jsfiddle.net/ferahl/y5pcua68/7/


7
これは私にはうまくいきません。これはReact.cloneElement()内では定義されていません
Patrick

12
この回答は機能しません。value渡されたものdoSomethingが失われます。
Dave

3
@DominicTobias Arg、申し訳ありませんが、console.logを切り替えて警告し、2つのパラメーターを1つの文字列に連結するのを忘れていました。
デイブ

1
この回答は非常に役に立ちましたが、ここに記載されていない問題に遭遇し、変更された新しいものなのか、それとも私の奇妙なことなのか疑問に思いました。子要素を複製すると、this.props.children.props.childrenをcloneElementの3番目の引数に追加するまで、その子は古い要素に設定されました。
アフェニン2017

7
子が別のルートページから読み込まれたルート(v4)経由で読み込まれた場合はどうなりますか?
blamb

394

少しすっきりさせるには、次のことを試してください。

<div>
    {React.cloneElement(this.props.children, { loggedIn: this.state.loggedIn })}
</div>

編集:複数の個別の子で使用するには(子自体がコンポーネントである必要があります)、実行できます。16.8.6でテスト済み

<div>
    {React.cloneElement(props.children[0], { loggedIn: true, testingTwo: true })}
    {React.cloneElement(props.children[1], { loggedIn: true, testProp: false })}
</div>

10
私は最も評価された回答を使用していましたが、これははるかに簡単です。このソリューションは、react-routerのサンプルページでも使用されています。
captDaylight 2016年

10
誰かがこれがどのように機能するか(またはそれが実際に何をするか)説明できますか?ドキュメントを読んでこれがどのように子孫に降りて、各小道具にその小道具を追加するのかわかりませんでした-それが意図されていることですか?もしそうなら、これがそれが何をするのかをどうやって知るのですか?...要素を期待している...に不透明なデータ構造(this.props.children)を渡すことが有効であることさえまったく明らかではありませんcloneElement
GreenAsJade 2016年

51
正確には、これは複数の子供で動作するようには見えません。
ダニタ2016年

17
したがって、誰かが子を1つだけコンポーネントに渡したときに機能するコードを作成できますが、別の子を追加するとクラッシュします...額面どおりに聞こえませんか?それは、すべての子供に小道具を渡すことについて具体的に尋ねたOPの罠のようです。
GreenAsJade 2016

10
@GreenAsJadeは、コンポーネントが単一の子を期待している限り問題ありません。コンポーネントを介して、propTypesが単一の子を期待することを定義できます。React.Children.only関数は唯一の子を返すか、複数ある場合は例外をスローします(ユースケースがなければこれは存在しません)。
チェンバレン

80

これを試して

<div>{React.cloneElement(this.props.children, {...this.props})}</div>

それは、反応15.1を使用して私のために働いた。


3
タグでReact.cloneElement()囲まずに直接戻ることはでき<div>ますか?子が<span>(または他の何か)であり、そのタグ要素タイプを保持したい場合はどうでしょうか
adrianmc 2016

1
子が1人の場合、ラッパーを省略できます。このソリューションは1人の子に対してのみ機能するため、そうです。
ThaJay

1
私のために働く。<div>を囲まなくてもかまいません。
クラッシュオーバーライド2017年

4
子を1つだけ受け取ることを明示的に強制する必要がある場合、複数の子React.cloneElement(React.Children.only(this.props.children), {...this.props})が渡されるとエラーがスローされます。その後、divでラップする必要はありません。
itsananderson 2017

1
この回答は、TypeError:循環オブジェクト値を生成する場合があります。子供の小道具の1つをそれ自体にしたい場合を除きlet {children, ...acyclicalProps} = this.props、次にを使用しReact.cloneElement(React.Children.only(children), acyclicalProps)ます。
Parabolord

69

子供を導くために小道具を渡します。

他のすべての回答を見る

コンテキストを介して、共有されたグローバルデータをコンポーネントツリーに渡す

コンテキストは、現在認証されているユーザー、テーマ、優先言語など、Reactコンポーネントのツリーで「グローバル」と見なすことができるデータを共有するように設計されています。1

免責事項:これは更新された回答であり、以前の回答は古いコンテキストAPIを使用していました

それは消費者/提供の原則に基づいています。まず、コンテキストを作成します

const { Provider, Consumer } = React.createContext(defaultValue);

次に経由して

<Provider value={/* some value */}>
  {children} /* potential consumers */
<Provider />

そして

<Consumer>
  {value => /* render something based on the context value */}
</Consumer>

プロバイダーの子孫であるすべてのコンシューマーは、プロバイダーのバリュープロップが変更されるたびに再レンダリングされます。プロバイダーからその子孫のコンシューマーへの伝播は、shouldComponentUpdateメソッドの影響を受けないため、祖先コンポーネントが更新から解放されても、コンシューマーは更新されます。 1

完全な例、半疑似コード。

import React from 'react';

const { Provider, Consumer } = React.createContext({ color: 'white' });

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      value: { color: 'black' },
    };
  }

  render() {
    return (
      <Provider value={this.state.value}>
        <Toolbar />
      </Provider>
    );
  }
}

class Toolbar extends React.Component {
  render() {
    return ( 
      <div>
        <p> Consumer can be arbitrary levels deep </p>
        <Consumer> 
          {value => <p> The toolbar will be in color {value.color} </p>}
        </Consumer>
      </div>
    );
  }
}

1 https://facebook.github.io/react/docs/context.html


6
受け入れられた回答とは異なり、これは親の下に他の要素が含まれている場合でも適切に機能します。これは間違いなく最良の答えです。
Zaptree、2016

6
小道具!=コンテキスト
Petr Peller、

コンテキストを介して伝播する変更に依存することはできません。可能であれば、小道具を使用します。
ThaJay 2017年

1
分からないかもしれませんが、「コンテキストが小道具を利用可能にする」と言うのは間違っていませんか?私が最後にコンテキストを使用したとき、それは別のものでした(つまりthis.context)-それは魔法のようにコンテキストを小道具とマージしませんでした。コンテキストを意図的に設定して使用する必要がありましたが、それはまったく別のことです。
Josh、

あなたは完全に理解します、それは間違っていました。回答を編集しました。
リュボミール2017

48

ネストされた子供に小道具を渡す

React 16.6への更新により、React.createContextおよびcontextTypeを使用できるようになりました

import * as React from 'react';

// React.createContext accepts a defaultValue as the first param
const MyContext = React.createContext(); 

class Parent extends React.Component {
  doSomething = (value) => {
    // Do something here with value
  };

  render() {
    return (
       <MyContext.Provider value={{ doSomething: this.doSomething }}>
         {this.props.children}
       </MyContext.Provider>
    );
  }
}

class Child extends React.Component {
  static contextType = MyContext;

  onClick = () => {
    this.context.doSomething(this.props.value);
  };      

  render() {
    return (
      <div onClick={this.onClick}>{this.props.value}</div>
    );
  }
}


// Example of using Parent and Child

import * as React from 'react';

class SomeComponent extends React.Component {

  render() {
    return (
      <Parent>
        <Child value={1} />
        <Child value={2} />
      </Parent>
    );
  }
}

React.createContextはどこ輝くReact.cloneElementの場合は、ネストされたコンポーネントを扱うことができませんでした

class SomeComponent extends React.Component {

  render() {
    return (
      <Parent>
        <Child value={1} />
        <SomeOtherComp><Child value={2} /></SomeOtherComp>
      </Parent>
    );
  }
}

3
=>関数が悪い習慣である理由を説明できますか?=>関数は、イベントハンドラーをバインドしてthisコンテキストを取得するのに役立ちます
Kenneth Truong

@KennethTruongは、レンダリングするたびに関数を作成するためです。
itdoesntwork

9
真実ではない@itdoesntwork。クラスの作成時にのみ新しい関数が作成されます。その..機能をレンダリング中に作成されていない
ケネス・チュオン

@KennethTruong reactjs.org/docs/faq-functions.html#arrow-function-in-renderレンダリングでの矢印関数について話していると思いました。
itdoesntwork

24

を使用することができReact.cloneElementます。アプリケーションでの使用を開始する前に、それがどのように機能するかを知っておくとよいでしょう。これはで紹介さReact v0.13れています。詳細については、この作業と一緒に何かを読んでください。

<div>{React.cloneElement(this.props.children, {...this.props})}</div>

そのため、Reactのドキュメントの行を用意して、すべてがどのように機能し、どのように利用できるかを理解してください。

React v0.13 RC2では、React.addons.cloneWithPropsと同様に、次のシグネチャを持つ新しいAPIを導入します。

React.cloneElement(element, props, ...children);

cloneWithPropsとは異なり、この新しい関数には、transferPropsToからの機能がないのと同じ理由で、スタイルとclassNameをマージするための組み込みの動作はありません。マジックの完全なリストが正確に何であるかは誰にもわかりません。そのため、コードについて推論することが難しくなり、スタイルが別のシグネチャを持っている場合(たとえば、今後のReact Nativeで)再利用することが難しくなります。

React.cloneElementは、ほぼ以下と同等です。

<element.type {...element.props} {...props}>{children}</element.type>

ただし、JSXやcloneWithPropsとは異なり、refも保持されます。これは、refを持つ子を取得した場合、誤って祖先からそれを盗むことがないことを意味します。新しい要素に同じ参照が添付されます。

一般的なパターンの1つは、子供にマップして新しい小道具を追加することです。cloneWithPropsが参照を失うことについて報告された多くの問題があり、コードについて推論することが難しくなっています。これで、cloneElementで同じパターンに従うと、期待どおりに機能します。例えば:

var newChildren = React.Children.map(this.props.children, function(child) {
  return React.cloneElement(child, { foo: true })
});

注:React.cloneElement(child、{ref: 'newRef'})はrefをオーバーライドするため、callback-refsを使用しない限り、2つの親が同じ子へのrefを持つことはまだ不可能です。

プロップは現在不変であるため、これはReact 0.13を導入する上で重要な機能でした。多くの場合、アップグレードパスは要素のクローンを作成することですが、そうすることで参照を失う可能性があります。したがって、ここにはより優れたアップグレードパスが必要でした。Facebookでコールサイトをアップグレードしているときに、この方法が必要であることに気付きました。私たちはコミュニティから同じフィードバックを得ました。そのため、最終リリースの前に別のRCを作成して、これを確実に実現することにしました。

最終的にReact.addons.cloneWithPropsを廃止する予定です。私たちはまだそれをしていませんが、これはあなた自身の使用について考え始め、代わりにReact.cloneElementの使用を検討する良い機会です。実際に削除する前に、必ず非推奨通知を含むリリースを出荷するので、すぐに対処する必要はありません。

もっとここに ...


18

プロパティを転送できる最良の方法childrenは関数のようなものです

例:

export const GrantParent = () => {
  return (
    <Parent>
      {props => (
        <ChildComponent {...props}>
          Bla-bla-bla
        </ChildComponent>
      )}
    </Parent>
  )
}

export const Parent = ({ children }) => {
    const somePropsHere = { //...any }
    <>
        {children(somePropsHere)}
    </>
}

1
これは、受け入れられた回答よりもずっと簡単です(そしてパフォーマンスにとってはより良いですか?)。
Shikyo

2
これは、子が関数である必要があり、denest入れ子コンポーネントには機能しません
デジタル錯覚

@digitalillusion、どういう意味かわかりませんnested components。Reactにはネストされたパターンはなく、コンポジションだけがあります。はい、子は関数でなければなりません。これは有効なJSX子であるため、競合は発生しません。例を挙げられnesting componentsますか?
Nick Ovchinnikov

1
あなたは正しい深くネストされた子供の場合はうまくとして扱うことができます<Parent>{props => <Nest><ChildComponent /></Nest>}</Parent>の代わりに、(動作しない)<Parent><Nest>{props => <ChildComponent />}</Nest></Parent>私は、これが最良の答えであることに同意して
デジタル錯覚

しようとすると、私は次のことを受け取る:TypeError: children is not a function
ライアン・プレンティス

6

このポインターの代わりにそれを使用て機能させるには、上記の受け入れられた回答を修正する必要がありました。このマップ機能の範囲内ではありませんでしたdoSomethingのの関数が定義されました。

var Parent = React.createClass({
doSomething: function() {
    console.log('doSomething!');
},

render: function() {
    var that = this;
    var childrenWithProps = React.Children.map(this.props.children, function(child) {
        return React.cloneElement(child, { doSomething: that.doSomething });
    });

    return <div>{childrenWithProps}</div>
}})

更新:この修正はECMAScript 5用であり、ES6ではvar that = thisに必要はありません。


13
またはそのまま使用bind()
plus-

1
またはレキシカルスコープにバインドする矢印関数を使用して、私の答えを更新しました
Dominic

doSomethingdoSomething: function(obj) { console.log(obj) }this.props.doSomething(obj)"obj"
たとえば

4
@ plus-これは古いことを知っていますが、ここでbindを使用するのはひどい考えです。bindは、コンテキストを新しいものにバインドする新しい関数を作成します。基本的には、applyメソッドを呼び出す関数です。使用してbind()レンダリング機能では、新しい機能にrenderメソッドが呼び出されるたびに作成されます。
Bamieh 2016年

6

1人以上の子供を考慮したよりクリーンな方法

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

これは私にはうまくいきません、それはエラーを出します:子供が定義されていません。
Deelux 2016年

子供の代わりに@Deelux this.props.children
Martin Dawson

これは、子を自分自身の子としてで渡しthis.propsます。一般的に、シバン全体ではなく、特定の小道具を使用してクローンを作成することをお勧めします。
Andy

パス{...this.props}はうまくいきませんでしたが、{...child.props}正しい方法ですか?
フェリペアウグスト

機能コンポーネントの場合:React.Children.map(children, child => React.cloneElement(child, props))
vsync

5

テキスト文字列のように、Reactコンポーネントではない子が存在するという問題には、どの回答も対処していません。回避策は次のようなものです。

// Render method of Parent component
render(){
    let props = {
        setAlert : () => {alert("It works")}
    };
    let childrenWithProps = React.Children.map( this.props.children, function(child) {
        if (React.isValidElement(child)){
            return React.cloneElement(child, props);
        }
          return child;
      });
    return <div>{childrenWithProps}</div>

}

5

あなたはもう必要ありません{this.props.children}。これrenderRoute、in を使用して子コンポーネントをラップし、通常どおりに小道具を渡すことができます。

<BrowserRouter>
  <div>
    <ul>
      <li><Link to="/">Home</Link></li>
      <li><Link to="/posts">Posts</Link></li>
      <li><Link to="/about">About</Link></li>
    </ul>

    <hr/>

    <Route path="/" exact component={Home} />
    <Route path="/posts" render={() => (
      <Posts
        value1={1}
        value2={2}
        data={this.state.data}
      />
    )} />
    <Route path="/about" component={About} />
  </div>
</BrowserRouter>

2
レンダリングプロップはReact(reactjs.org/docs/render-props.html)で標準になり、この質問に対する新しい承認済み回答として検討する価値があります。
Ian Danforth

19
これは質問に対する答えですか?
Maximo Dominguez、2018年

4

Parent.jsx:

import React from 'react';

const doSomething = value => {};

const Parent = props => (
  <div>
    {
      !props || !props.children 
        ? <div>Loading... (required at least one child)</div>
        : !props.children.length 
            ? <props.children.type {...props.children.props} doSomething={doSomething} {...props}>{props.children}</props.children.type>
            : props.children.map((child, key) => 
              React.cloneElement(child, {...props, key, doSomething}))
    }
  </div>
);

Child.jsx:

import React from 'react';

/* but better import doSomething right here,
   or use some flux store (for example redux library) */
export default ({ doSomething, value }) => (
  <div onClick={() => doSomething(value)}/>
);

およびmain.jsx:

import React from 'react';
import { render } from 'react-dom';
import Parent from './Parent';
import Child from './Child';

render(
  <Parent>
    <Child/>
    <Child value='1'/>
    <Child value='2'/>
  </Parent>,
  document.getElementById('...')
);

こちらの例をご覧くださいhttps : //plnkr.co/edit/jJHQECrKRrtKlKYRpIWl?p=preview



4

小道具渡したい子が複数ある場合は、React.Children.mapを使用してこのようにできます。

render() {
    let updatedChildren = React.Children.map(this.props.children,
        (child) => {
            return React.cloneElement(child, { newProp: newProp });
        });

    return (
        <div>
            { updatedChildren }
        </div>
    );
}

コンポーネントに子が1つしかない場合は、マッピングする必要はありません。すぐにcloneElementを実行できます。

render() {
    return (
        <div>
            {
                React.cloneElement(this.props.children, {
                    newProp: newProp
                })
            }
        </div>
    );
}

3

のドキュメントによると cloneElement()

React.cloneElement(
  element,
  [props],
  [...children]
)

elementを開始点として新しいReact要素を複製して返します。結果の要素には、元の要素の小道具が含まれ、新しい小道具は浅くマージされます。新しい子供が既存の子供を置き換えます。元の要素のキーと参照が保持されます。

React.cloneElement() ほぼ次と同等です:

<element.type {...element.props} {...props}>{children}</element.type>

ただし、参照も保持されます。これは、refを持つ子を取得した場合、誤って祖先からそれを盗むことがないことを意味します。新しい要素に同じ参照が添付されます。

したがって、cloneElementは、子供にカスタムプロップを提供するために使用するものです。ただし、コンポーネントに複数の子が存在する可能性があり、ループする必要があります。他の答えが示唆するのは、を使用してそれらをマッピングすることReact.Children.mapです。ただし、要素のキーの追加とプレフィックスとしての追加の変更React.Children.mapとは異なります。詳細については、この質問を確認してください:React.cloneElement.$ React.Children.map内のReact.cloneElementが要素キーを変更しています

それを避けたい場合は、代わりに次のforEachような関数を使用する必要があります

render() {
    const newElements = [];
    React.Children.forEach(this.props.children, 
              child => newElements.push(
                 React.cloneElement(
                   child, 
                   {...this.props, ...customProps}
                )
              )
    )
    return (
        <div>{newElements}</div>
    )

}

2

@and_restの回答に加えて、これは子供を複製してクラスを追加する方法です。

<div className="parent">
    {React.Children.map(this.props.children, child => React.cloneElement(child, {className:'child'}))}
</div>

2

レンダープロップはこのシナリオを処理する適切な方法だと思います

次のように見えるようにParentコードをリファクタリングすることにより、Parentに子コンポーネントで使用される必要な小道具を提供させます。

const Parent = ({children}) => {
  const doSomething(value) => {}

  return children({ doSomething })
}

次に、子コンポーネントで、親が提供する関数に次のようにアクセスできます。

class Child extends React {

  onClick() => { this.props.doSomething }

  render() { 
    return (<div onClick={this.onClick}></div>);
  }

}

ファイナル構造は次のようになります。

<Parent>
  {(doSomething) =>
   (<Fragment>
     <Child value="1" doSomething={doSomething}>
     <Child value="2" doSomething={doSomething}>
    <Fragment />
   )}
</Parent>

親が別のクラスコンポーネントのテキストエリアである{children}のラッパーである場合はどうなりますか?
Adebayo

2

方法1-子を複製する

const Parent = (props) => {
   const attributeToAddOrReplace= "Some Value"
   const childrenWithAdjustedProps = React.Children.map(props.children, child =>
      React.cloneElement(child, { attributeToAddOrReplace})
   );

   return <div>{childrenWithAdjustedProps }</div>
}

方法2-構成可能なコンテキストを使用する

コンテキストにより、間にあるコンポーネントを介してプロップとして明示的に渡すことなく、深い子コンポーネントにプロップを渡すことができます。

コンテキストには欠点があります:

  1. データは通常の方法では流れません-小道具を介して。
  2. コンテキストを使用すると、コンシューマーとプロバイダーの間にコントラクトが作成されます。コンポーネントを再利用するために必要な要件を理解して再現することは、より難しい場合があります。

構成可能なコンテキストの使用

export const Context = createContext<any>(null);

export const ComposableContext = ({ children, ...otherProps }:{children:ReactNode, [x:string]:any}) => {
    const context = useContext(Context)
    return(
      <Context.Provider {...context} value={{...context, ...otherProps}}>{children}</Context.Provider>
    );
}

function App() {
  return (
      <Provider1>
            <Provider2> 
                <Displayer />
            </Provider2>
      </Provider1>
  );
}

const Provider1 =({children}:{children:ReactNode}) => (
    <ComposableContext greeting="Hello">{children}</ComposableContext>
)

const Provider2 =({children}:{children:ReactNode}) => (
    <ComposableContext name="world">{children}</ComposableContext>
)

const Displayer = () => {
  const context = useContext(Context);
  return <div>{context.greeting}, {context.name}</div>;
};

少し遅れますが、表記を説明していただけ{children}:{children:ReactNode}ますか?
カミーユ

@camille、それはTypescriptのことです。今それを見ると、Javascriptで答えるだけで、Typescriptを書いたとしても、私はそれを別の方法で行うでしょう。将来的には編集するかもしれません。
Ben Carp

1
@camille、基本的には、キーを持つ値"children"がタイプであることを意味しますReactNode
Ben Carp

1

これを行うための最も洗練された方法:

    {React.cloneElement(this.props.children, this.props)}

5
this.props.childrenを子のthis.props.childrenにコピーしませんか?そして実際には子供を自分自身にコピーしますか?
Arshabh Agarwal

1

子要素が1つだけの場合は、これを行う必要があります。

{React.isValidElement(this.props.children)
                  ? React.cloneElement(this.props.children, {
                      ...prop_you_want_to_pass
                    })
                  : null}

0

これはあなたが必要としたものですか?

var Parent = React.createClass({
  doSomething: function(value) {
  }
  render: function() {
    return  <div>
              <Child doSome={this.doSomething} />
            </div>
  }
})

var Child = React.createClass({
  onClick:function() {
    this.props.doSome(value); // doSomething is undefined
  },  
  render: function() {
    return  <div onClick={this.onClick}></div>
  }
})

4
いいえ、ラッパーのコンテンツを特定のコンテンツに制限したくありません。
プラス

0

何らかの理由でReact.childrenが機能しませんでした。これは私のために働いたものです。

子供にクラスを追加したかっただけです。小道具の変更に似ています

 var newChildren = this.props.children.map((child) => {
 const className = "MenuTooltip-item " + child.props.className;
    return React.cloneElement(child, { className });
 });

 return <div>{newChildren}</div>;

ここでの秘訣React.cloneElementです。同様の方法で小道具を渡すことができます


0

レンダリングプロップは、この問題に対する最も正確なアプローチです。子コンポーネントを子プロップとして親コンポーネントに渡す代わりに、親に子コンポーネントを手動でレンダリングさせます。Renderはreactの組み込みプロップで、関数パラメータを受け取ります。この関数では、カスタムコンポーネントを使用して、親コンポーネントに必要なものをレンダリングさせることができます。基本的には子プロップと同じことを行いますが、よりカスタマイズ可能です。

class Child extends React.Component {
  render() {
    return <div className="Child">
      Child
      <p onClick={this.props.doSomething}>Click me</p>
           {this.props.a}
    </div>;
  }
}

class Parent extends React.Component {
  doSomething(){
   alert("Parent talks"); 
  }

  render() {
    return <div className="Parent">
      Parent
      {this.props.render({
        anythingToPassChildren:1, 
        doSomething: this.doSomething})}
    </div>;
  }
}

class Application extends React.Component {
  render() {
    return <div>
      <Parent render={
          props => <Child {...props} />
        }/>
    </div>;
  }
}

コードペンでの例


0

機能コンポーネントを使用する場合、にTypeError: Cannot add property myNewProp, object is not extensible新しいプロパティを設定しようとすると、エラーが発生することがよくありますprops.children。小道具のクローンを作成し、新しい小道具を使用して子自体をクローン化することで、これに対する回避策があります。

const MyParentComponent = (props) => {
  return (
    <div className='whatever'>
      {props.children.map((child) => {
        const newProps = { ...child.props }
        // set new props here on newProps
        newProps.myNewProp = 'something'
        const preparedChild = { ...child, props: newProps }
        return preparedChild
      })}
    </div>
  )
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.