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

<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。亲子关系;

function Wrapper() {
  return (
    <div>
      <OuterComponent>
        <InnerComponent />
      </OuterComponent>
    </div>
  );
}
function OuterComponent(props) {
  return props.children;
}
function InnerComponent() {
  return <div>Hi! I'm in inner component!</div>;
}
export default Wrapper;

例2。嵌套的组件:

function Wrapper() {
  return (
    <div>
      <OuterComponent />
    </div>
  );
}
function OuterComponent(props) {
  return <InnerComponent />
}
function InnerComponent() {
  return <div>Hi! I'm in inner component!</div>;
}
export default Wrapper;

如上所述,道具传递在例1中有效。

下面的文章对此进行了解释https://medium.com/@justynazet/passing-props-to-props-children-using-react-cloneelement- andrend-props -pattern-896da70b24f6

其他回答

我确实努力让列出的答案工作,但失败了。最终,我发现问题在于正确地建立亲子关系。仅仅在其他组件中嵌套组件并不意味着存在父子关系。

例1。亲子关系;

function Wrapper() {
  return (
    <div>
      <OuterComponent>
        <InnerComponent />
      </OuterComponent>
    </div>
  );
}
function OuterComponent(props) {
  return props.children;
}
function InnerComponent() {
  return <div>Hi! I'm in inner component!</div>;
}
export default Wrapper;

例2。嵌套的组件:

function Wrapper() {
  return (
    <div>
      <OuterComponent />
    </div>
  );
}
function OuterComponent(props) {
  return <InnerComponent />
}
function InnerComponent() {
  return <div>Hi! I'm in inner component!</div>;
}
export default Wrapper;

如上所述,道具传递在例1中有效。

下面的文章对此进行了解释https://medium.com/@justynazet/passing-props-to-props-children-using-react-cloneelement- andrend-props -pattern-896da70b24f6

一些原因。孩子不适合我。这对我来说很管用。

我只想给这个child添加一个类。类似于更换道具

 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。你可以用类似的方式通过任何道具

考虑到一个或多个孩子,这样更干净

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

在使用函数组件时,当您尝试在props.children上设置新属性时,经常会得到TypeError:不能添加属性myNewProp, object is not extensible错误。有一个工作围绕这个克隆道具,然后克隆孩子本身与新的道具。

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>
  )
}

我认为渲染道具是处理这种情况的合适方法

你可以让父组件提供子组件中使用的必要的道具,通过重构父组件代码使其看起来像这样:

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>