一尘不染

JavaScript如何将道具传递给{this.props.children}

javascript

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

<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}定义包装器组件时,如何将某些属性传递给其所有子组件?


阅读 906

收藏
2020-04-25

共1个答案

一尘不染

Cloning children with new props

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

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

class Parent extends React.PureComponent {
  doSomething = value => {
    console.log('doSomething called by child with value:', value);
  }

  render() {
    const childrenWithProps = React.Children.map(this.props.children, child =>
      React.cloneElement(child, { doSomething: this.doSomething })
    );

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

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

Calling children as a function

您也可以将道具传递给带有渲染道具的孩子。在这种方法中,子代(可以是children或任何其他prop名称)是一个函数,可以接受您要传递的任何参数并返回子代:

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

class Parent extends React.PureComponent {
  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>{this.props.children(this.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>或简单地<>返回一个数组。

2020-04-25