4

I'am searching for this but i couldn't find a proper answer. Is it possible to use React Router like this inside React Component;

import { Route, Switch } from 'react-router'    
import LandingLayout from '../../layouts/landing/LandingLayout'
import AppLayout from '../../layouts/app/AppLayout'

<Switch>
  <LandingLayout>
    <Route path="/" exact="true" component={Home} />
    <Route path='/login' component={Login} />
    <Route path='/signup' component={Signup} />
  </LandingLayout>
  <AppLayout>
    <Route path='/dashboard' component={DashboardPage} />
    <Route path='/users' component={UserList} />
    <Route path='/u/:username' component={AccountPage} />
  </AppLayout>
  <Route component={NotFound} />
</Switch>
3
  • Are you getting any error? Commented Apr 1, 2018 at 6:14
  • First of all, at "/dashboard" or "/users" route the page comes with Landing Layout, it must render App Layout and content section in the middle empty. But at "/" home or login page it renders correctly. Commented Apr 1, 2018 at 6:16
  • Also server.js logs this. Warning: Failed prop type: Invalid prop exact of type string supplied to Route, expected boolean. in Route in Routes in Router in StaticRouter in Provider in LocaleProvider Commented Apr 1, 2018 at 6:18

2 Answers 2

1

Switch only works with Route and since you render LandingLayout and AppLayout without Route, both of them will be rendered defaultly and while its ok to add the Routes as Child Routes, its better if you add them inside the component and since you want to have the LandingLayout and AppLayout render separately you would have to write them as routes

import { Route, Switch } from 'react-router'    
import LandingLayout from '../../layouts/landing/LandingLayout'
import AppLayout from '../../layouts/app/AppLayout'

<Switch>
  <Route path="/landing" component={LandingLayout}/> 
  <Route path="/app" component={AppLayout} />
  <Route component={NotFound} />
</Switch>

LandingLayout

render() {
   return (
       <div>
          {/* other things*/}
          <Route path={this.props.match.path} exact="true" component={Home} />
          <Route path={`${this.props.match.path}/login`} component={Login} />
          <Route path={`${this.props.match.path}/signup`} component={Signup} />
       </div>
   )
}

AppLayout

render() {
   return (
       <div>
          {/* other things*/}
          <Route path={`${this.props.match.path}/dashboard`} exact="true" component={DashboardPage} />
          <Route path={`${this.props.match.path}/users`} component={Login} />
          <Route path={`${this.props.match.path}/u/:username`} component={AccountPage} />
       </div>
   )
}
Sign up to request clarification or add additional context in comments.

4 Comments

Do note that this.props.match.url is recommended for Links. Sometimes people use this.props.match.path for both Route and Link
Thank you for alternatives but this is not the appropriate solution. I can not use routes like "/landing/home" or "/landing/login".
Routes must be like these; “/“ “/login” “/signup” “/dashboard” “/users“ And so on..
Basically i want to use 2 master layouts (views). One for landing page, the other one for app. How can i achieve this.
1

After lots of research i got the right answer for my case.

First of all my React application is a server rendered app. Second; i am using React Router Switch because of performance related issues.

Above solution not worked for me because of my app architecture and i got some errors like;

You should not use Route component and Route children in the same route; Route children will be ignored

So here; i want to use React Router Switch with multiple layouts. And here is how to do it.

First you will create a custom Router component which combines the Layout and Component. Say "AppRouter"

const AppRouter = ({ component: Component, layout: Layout, ...rest }) => (
   <Route {...rest} render={props => (
     <Layout>
       <Component {...props} />
     </Layout>
   )} />
)

Second; for public and private routes there must be two different layout wrapper

const LandingRouteLayout = props => (
  <div>
    <LandingLayout {...props}/>
  </div>
)

const AppRouteLayout = props => (
 <div>
   <AppLayout {...props}/>
 </div>
)

Last; Routes

const Routes = () => {
  return (
    <Switch>
      <AppRoute exact path="/" layout={LandingRouteLayout} component={Home} />
      <AppRoute path="/login" layout={LandingRouteLayout} component={Login} />
      <AppRoute path="/signup" layout={LandingRouteLayout} component={Signup} />
      <AppRoute path="/t/:token" layout={AppRouteLayout} component={SetToken} />
      <AppRoute path='/dashboard' layout={AppRouteLayout} component={DashboardPage} />
      <AppRoute path="/u/:username" layout={AppRouteLayout} component={AccountPage} />
      <Route component={NotFound} />
    </Switch>
  )
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.