1. ホーム
  2. ジャバスクリプト

[解決済み】 {this.props.children} に props を渡すには?}

2022-03-23 21:59:05

質問

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

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

どのように解決するのですか?

新しいプロップでの子のクローン

を使用することができます。 React.Children を使用して子要素を繰り返し、新しいプロップ (浅いマージ) を使用して各要素をクローンします。 React.cloneElement . 例えば

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

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

  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, { doSomething });
    }
    return child;
  });

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

function App() {
  return (
    <Parent>
      <Child value={1} />
      <Child value={2} />
    </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 や他のプロパティの名前) は、あなたが渡したい任意の引数を受け取り、子プロセスを返すことができる関数です。

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

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

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

function App() {
  // doSomething is the arg we passed in Parent, which
  // we now pass through to Child.
  return (
    <Parent>
      {doSomething => (
        <React.Fragment>
          <Child doSomething={doSomething} value={1} />
          <Child doSomething={doSomething} value={2} />
        </React.Fragment>
      )}
    </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>

の代わりに <React.Fragment> 或いは単に <> は、必要なら配列を返すこともできます。