简体   繁体   中英

In ReactJS, how do I render one component within another?

I'm writing a ReactJS app, and want to show a landing page which displays either a Sign In form or a Register form, depending on which link was followed.

So far, my App component looks like this:

const App = () => (
  <Router>
    <div>
      <Route path={ROUTES.LANDING}  render={(props) => <LandingPage {...props} subPage={SignInPage} />}/>
      <Route path={ROUTES.SIGNIN}   render={(props) => <LandingPage {...props} subPage={SignInPage} />}/>
      <Route path={ROUTES.REGISTER} render={(props) => <LandingPage {...props} subPage={RegisterPage} />}/>
      <Route render={(props) => <LandingPage {...props} subPage={SignInPage} />}/>
    </div>
  </Router>
);

Now, I'm not sure how to get the actual sub-pages to show within the landing page.

In my landingpage component, I have this:

class LandingPage extends Component {
  constructor(props) {
    super(props);

    this.state = {props}

  }

  render() {

    return (
      <div className="wrapper">
        <div>{this.state.subPage}</div>
      </div>
    );
  }
}

export default LandingPage;

but it doesn't show anything when I go to 'landingpage/signin'. I can see in the console that this.state.subPage contains the correct component, and when I change the Route to show the SignInPage directly, that works fine, so the SignInPage is definitely working ok on its own.

My SignInPage component contains:

const SignInPage = () => (
  <div>
    <p>Sign In</p>
    <SignInForm />
  </div>
);

class SignInFormBase extends Component {
  constructor(props) {
    super(props);

  }

  onSubmit = event => {
    // This will handle form submission
  };

  render() {
    return (
      <form onSubmit={this.onSubmit}>
        <input name="email" placeholder="Email Address" />
        <input name="password" type="password" placeholder="Password" />
        <button type="submit">Sign In</button>
      </form>
    );
  }
}
const SignInForm = compose(
  withRouter,
  withFirebase,
)(SignInFormBase);

export default SignInPage;

export { SignInForm };

I'm guessing that maybe the issue is that SignInForm is a component but SignInPage isn't? But I'm new to React, so I don't know how to reconfigure them!

What can I try next?

Since you are passing the subPage to the LandingPage as props, you can take that component from props and render it like below

class LandingPage extends Component {
  constructor(props) {
    super(props);

  }

  render() {
    const SubPage = this.props.subPage;
    return (
      <div className="wrapper">
        <div><SubPage /></div>
      </div>
    );
  }
}

export default LandingPage;

NOTE: You don't need to copy props into state

In App component:

<Route render={(props) => <LandingPage {...props}><SignInPage /></LandingPage>}/>

In landingpage component:

<div className="wrapper">
 <div>{this.props.children}</div>
</div>

Instead of explicitly passing the components as props to LandingPage component, you can nest them inside the LandingPage component

<LandingPage {...props}>
   <SignInPage />
</LandingPage>

SignIn component will be passed to the LandingPage component as props and will be accessible using props.children

return (
  <div className="wrapper">
    {this.props.children}
  </div>
);

An advantage of this approach is that you can nest as many components inside LandingPage component and they all will be rendered inside LandingPage component using this.props.children

Your routes will look like this after this change

<Route path={ROUTES.LANDING} render={(props) => <LandingPage {...props}> <SignInPage/> </LandingPage> }/>
<Route path={ROUTES.SIGNIN} render={(props) => <LandingPage {...props}> <SignInPage/> </LandingPage>}/>
<Route path={ROUTES.REGISTER} render={(props) => <LandingPage {...props}> <RegisterPage/> </LandingPage>}/>
<Route render={(props) => <LandingPage {...props}> <SignInPage/> </LandingPage>}/>

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