javascript - 如何将 Prop 传递给 {this.props.children}

标签 javascript reactjs

我正在尝试找到正确的方法来定义一些可以以通用方式使用的组件:

<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}要定义一个包装器组件,如何将一些属性传递给它的所有子组件?

最佳答案

用新 Prop 克隆 child

您可以使用 React.Children遍历子元素,然后使用 React.cloneElement 使用新的 Prop (浅合并)克隆每个元素.

查看代码注释为什么我不推荐这种方法。

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>

将 child 作为函数调用

或者,您可以通过 render props 将 Prop 传递给 child 。 .在这种方法中, child (可以是 children 或任何其他 Prop 名称)是一个可以接受您想要传递的任何参数并返回实际 child 的函数:

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 this component 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) => (
        <React.Fragment>
          <Child childName="Billy" sayHello={sayHello} />
          <Child childName="Bob" sayHello={sayHello} />
        </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>

关于javascript - 如何将 Prop 传递给 {this.props.children},我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32370994/

相关文章:

javascript - AngularJS 比较两个(作用域)数组并且只发布 'non-same' 结果(2018)

javascript - 取消内联 Onclick 的浏览器滚动重置

javascript - 使用 javascript,获取给定 x 和 y 位置的 div id

reactjs - React Hooks : how to prevent re-rendering the whole component when only the props. 子值变化?

javascript - 根据 React 中的输入字段过滤对象数组

html - &lt;input&gt; 不能作为 <tr> 的子项出现

javascript - 将 MySQL 表值从 PHP 脚本返回到 Javascript 函数 - 实时绘图

reactjs - 使用 Redux 两个 React 表单组件之间的通信

javascript - 还原。我无法理解如何连接定义为扩展 React.Component 的类的组件以便读取存储

javascript - QUnit setup() 在拆卸前调用每个测试