【问题标题】:React - How to pass props to a component passed as propReact - 如何将道具传递给作为道具传递的组件
【发布时间】:2018-08-01 19:49:00
【问题描述】:

我有一个 React 组件(React v15.5.4),您可以将其他组件传递给:

class CustomForm extends React.Component {
  ...
  render() {
    return (
      <div>
          {this.props.component}
      </div>
    );
  }
}

我有一个不同的组件使用它:

class SomeContainer extends React.Component {
  ...
  render() {
    let someObjectVariable = {someProperty: 'someValue'};
    return (
      <CustomForm 
         component={<SomeInnerComponent someProp={'someInnerComponentOwnProp'}/>}
         object={someObjectVariable}
      />
    );
  }
}

一切都很好,但我想将 someObjectVariable 属性传递给 CustomForm 内的子组件(在本例中为 SomeInnerComponent ),因为在实际代码中,您可以将多个组件传递给它,而不是像示例中那样只传递一个。

请注意,我还需要传递 SomeInnerComponent 自己的 props。

有没有办法做到这一点?

【问题讨论】:

  • 您说子组件CustomForm或SomeInnerComponent指的是哪一个?
  • @ArnoldGandarrilas SomeInnerComponent。我将编辑我的问题
  • 是的,我知道这是一种方式。但就像我说的,我可能会传递几个组件的数组,我不想为每个组件都这样做
  • 如果您要传递多个具有共享值的组件,使用context 会不会更好?这样,您将避免一遍又一遍地重新创建组件

标签: javascript reactjs


【解决方案1】:

您可以通过使用React.cloneElement 来实现。

像这样:

class CustomForm extends React.Component {
  ...
  render() {
    return (
      <div>
          {React.cloneElement(this.props.component,{ customProps: this.props.object })}
      </div>
    );
  }
}

工作代码:

class Parent extends React.Component{
  render() {
    return(
      <Child a={1} comp={<GChild/>} />
    )
  }
}

class Child extends React.Component{
  constructor(){
    super();
    this.state = {b: 1};
    this.updateB = this.updateB.bind(this);
  }
  
  updateB(){
    this.setState(prevState => ({b: prevState.b+1}))
  }
  
  render(){
    var Comp = this.props.comp;
    return (
      <div>
        {React.cloneElement(Comp, {b: this.state.b})}
        <button onClick={this.updateB}>Click to update b</button>
      </div>
    );
  }
}

const GChild = props => <div>{JSON.stringify(props)}</div>;
 
ReactDOM.render(
  <Parent />,
  document.getElementById('container')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

<div id='container' />

【讨论】:

  • 我不能使用选项 2,因为我需要传递 SomeInnerComponent 自己的道具。我将编辑问题以明确这一点。不过我会尝试 1
  • 哦,好吧,如果你想使用第二种方法,那么你可以做一件事。将所有这些道具值传递给 CustomForm 然后从 CustomForm 传递给 SomeInnerComponent。
  • 如果 CustomFor 上的值发生变化,是否会更新从 CustomForm 传递的子道具?看起来不像
  • 确实如此,我的代码有问题。因此,如果您只保留选项 1,我可以将其作为正确答案进行检查。非常感谢您的帮助。
【解决方案2】:

你可以像 SomeInnerComponent 一样做。

只需传递命名道具。

CustomForm内,

render() {

  const MyComponent = this.props.component; //stored it in some variable

    return (
      <div> 
         <MyComponent customProps = {this.props.object} /> //access object here and passed it or passed individual props
      </div>
    );
  }

编辑:

请查找working demo here

【讨论】:

  • 当我尝试此方法时收到此错误消息:“元素类型无效:预期为字符串(用于内置组件)或类/函数(用于复合组件)但得到:对象”
  • @DanielCalderonMori 应该可以工作。我想在里面。您的 SomeInnerComponent CustomForm 中的您正在尝试显示一个对象,说明您为什么会收到此类错误。请参阅更新的 DEMO codedandbox
  • 正如我提到的关键字working demo here。将myComponent and myComponent 分别替换为component and SomeInnerComponent 。 :D
  • 如果你通过someInnerComponent=SomeInnerComponent,即传递一个类,这有效,但如果你通过someInnerComponent={&lt;SomeInnerComponent someProp={'someInnerComponentOwnProp'}/&gt;},即传递一个对象,则无效,这就是问题所在。使用这种技术,您无法在顶层容器中设置一些道具,在中层容器中设置更多,您必须将它们全部设置在中层容器中。
【解决方案3】:

您有多种选择来实现您的要求。

class SomeContainer extends React.Component {
  ...
  render() {
   let someObjectVariable = {someProperty: 'someValue'};
    return (
      <CustomForm 
       component={<SomeInnerComponent propFromParent={someObjectVariable}/>}
       object={someObjectVariable}
      />
    );
  }

}

或者您可以克隆组件道具并按照 Mayank 所说的应用新道具。你的情况

class CustomForm extends React.Component {
  ...
  render() {
    return (
      <div>
        {React.cloneElement(this.props.component,
           {propFromParent:this.props.someObjectVariable})}
      </div>
  );
 }
}

【讨论】:

    【解决方案4】:

    您可以为此使用react-overrides。 创建自定义表单:

    import o from "react-overrides";
    
    const InnerComponent = () => null; // default
    
    class CustomForm extends React.Component {
      ...
      render() {
        return (
          <div>
              <InnerComponent {...o} />
          </div>
        );
      }
    }
    

    overrides props 处传递InnerComponent 的props 和组件:

    class SomeContainer extends React.Component {
      ...
      render() {
        let someObjectVariable = {someProperty: 'someValue'};
        return (
          <CustomForm 
             object={someObjectVariable}
             overrides={{
                 InnerComponent: {
                     component: SomeInnerComponent,
                     props: {
                         someProp: 'someInnerComponentOwnProp'
                     }
                 }
             }}
          />
        );
      }
    }
    
    

    【讨论】:

      【解决方案5】:
      <TextField place={"India"}> </TextField>
      

      在你的组件 TextField 中

      class TextField extends Component {
      
          constructor(props){
              super(props);
          }
      
          render() {
              return (
                  <div>
                      <input />
                      <button> {this.props.place} </button>
                  </div>
              )
            }
      }
      

      【讨论】:

        猜你喜欢
        • 2021-12-21
        • 2017-09-06
        • 2020-12-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-12-21
        • 2017-02-19
        • 1970-01-01
        相关资源
        最近更新 更多