Erdal SATIK
Erdal SATIK

Reputation: 670

Nested routes inside react component

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>

Upvotes: 4

Views: 8985

Answers (2)

Erdal SATIK
Erdal SATIK

Reputation: 670

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>
  )
}

Upvotes: 1

Shubham Khatri
Shubham Khatri

Reputation: 281606

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>
   )
}

Upvotes: 1

Related Questions