{this.props.children} に props を渡す方法 質問する

{this.props.children} に props を渡す方法 質問する

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

<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}ラッパー コンポーネントを定義するために を使用する場合、どのようにしてそのすべての子にプロパティを渡すかということです。

ベストアンサー1

新しい小道具を使って子供のクローンを作る

使用できますReact.Children子要素を反復処理し、各要素を新しいプロパティ(浅いマージ)で複製します。React.cloneElement

このアプローチを推奨しない理由については、コードコメントを参照してください。

cloneElement の使用は一般的ではなく、脆弱なコードにつながる可能性があります。一般的な代替手段を参照してください。出典: react.dev

const Child = ({ childName, sayHello }) => (
  <button onClick={() => sayHello(childName)}>{childName}</button>
);

function Parent({ children }) {
  // We pass this `sayHello` function into the child elements.
  function sayHello(childName) {
    console.log(`Hello from ${childName} the child`);
  }

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

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

function App() {
  // This approach is less type-safe and Typescript friendly since it
  // looks like you're trying to render `Child` without `sayHello`.
  // It's also confusing to readers of this code.
  return (
    <Parent>
      <Child childName="Billy" />
      <Child childName="Bob" />
    </Parent>
  );
}

ReactDOM.render(<App />, document.getElementById("container"));
<script src="https://unpkg.com/react@17/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@17/umd/react-dom.production.min.js"></script>
<div id="container"></div>

関数として子を呼び出す

あるいは、子供たちに小道具を渡すには、レンダリングプロップこのアプローチでは、 children (childrenまたは他の任意のプロパティ名) は、渡したい任意の引数を受け入れ、実際の children を返す関数です。

const Child = ({ childName, sayHello }) => (
  <button onClick={() => sayHello(childName)}>{childName}</button>
);

function Parent({ children }) {
  function sayHello(childName) {
    console.log(`Hello from ${childName} the child`);
  }

  // `children` of Parent must be a function
  // which returns the actual children. We can pass
  // it args to then pass into them as props (in this
  // case we pass `sayHello`).
  return <div>{children(sayHello)}</div>
}

function App() {
  // sayHello is the arg we passed in Parent, which
  // we now pass through to Child.
  return (
    <Parent>
      {(sayHello) => (
        <>
          <Child childName="Billy" sayHello={sayHello} />
          <Child childName="Bob" sayHello={sayHello} />
        </>
      )}
    </Parent>
  );
}

ReactDOM.render(<App />, document.getElementById("container"));
<script src="https://unpkg.com/react@17/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@17/umd/react-dom.production.min.js"></script>
<div id="container"></div>

おすすめ記事