简体   繁体   中英

React JS - Nesting components passed as props

I've written a container component in ReactJS and am passing in a prop to that component which is to be rendered as the 'main' content, like so:

class RegistrationContainer extends Component {

    render() {
        const MainContent = this.props.mainContent;

        return (
            <Row>
                <Col offset="lg-3" lg={6}>
                    <MainContent />
                </Col>
            </Row>
        );
    }

}

export default RegistrationContainer;

And I'm passsing to it a mainContent prop like so:

import RegistrationContainer from './RegistrationContainer';
import RegistrationEntryView from './RegistrationEntryView';

class RegistrationCodeEntry extends Component {

    render() {
        return (
            <RegistrationContainer mainContent={RegistrationEntryView} />
        );
    }
}

export default RegistrationCodeEntry;

My issue is that I would like RegistrationEntryView to have props, but can't seem to figure out how to define/pass in props on it. If I do the following I get an error:

class RegistrationCodeEntry extends Component {

    render() {
        const RegistrationView = <RegistrationEntryView someProp="blah" /> ;
        return (
            <RegistrationContainer mainContent={RegistrationView} />
        );
    }
}

export default RegistrationCodeEntry;

Error is as follows:

invariant.js?7313:42 Uncaught Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object. Check the render method of RegistrationContainer .

Is this something that this.props.children could solve? I've been struggling to get my head around the concept of that, so any advice on where I'm going wrong would be appreciated.

You can solve this with this.props.children like this

class RegistrationCodeEntry extends Component {

  render() {
    return (
      <RegistrationContainer>
          // Render it as children
          <RegistrationEntryView someProp="blah" />
      </RegistrationContainer>
    );
  }
}

then in your container

class RegistrationContainer extends Component {

  render() {

  const MainContent = this.props.mainContent;

  return (
    <Row>
      <Col offset="lg-3" lg={6}>
         // Render the passed children
        {this.props.children}
      </Col>
    </Row>
  );
 }
}

Your approach is correct. You just went wrong here:

<Row>
  <Col offset="lg-3" lg={6}>
    <MainContent />
  </Col>
</Row>

Instead do this:

<Row>
  <Col offset="lg-3" lg={6}>
    { MainContent }
  </Col>
</Row>

I personally think, this approach is better than using children.

When you did this - const RegistrationView = <RegistrationEntryView someProp="blah" /> ; The component was already rendered and converted to appropriate format. Hence you cannot re-render it with <MainContent /> . So using {} is correct in this case.

Good Luck!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM