Reputation: 3919
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?
Upvotes: 1
Views: 82
Reputation: 29344
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>}/>
Upvotes: 1
Reputation: 1833
In App component:
<Route render={(props) => <LandingPage {...props}><SignInPage /></LandingPage>}/>
In landingpage component:
<div className="wrapper">
<div>{this.props.children}</div>
</div>
Upvotes: 1
Reputation: 282120
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
Upvotes: 1