ReactFix
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • React
  • React Native
  • Programming
  • Object Oriented Programming

Saturday, November 5, 2022

[FIXED] How do I nest routes with React router

 November 05, 2022     javascript, react-router, react-router-dom, reactjs   

Issue

I have multiple layouts that should include different screens. Each layout has its own header, footer, and other things similar pages should share. Here is the code I came up with:

<BrowserRouter>
  <Route path={['/index', '/about']} component={BaseLayout}>
    <Route path="/index" component={Index} />
    <Route path="/about" component={About} />
  </Route>
  <Route path={['/sign-in', '/sign-up']} component={AuthLayout}>
    <Route path="/sign-in" component={SignIn} />
    <Route path="/sign-up" component={SignUp} />
  </Route>
  <Route path={['/stats'} component={DashboardLayout}>
    <Route path="/stats" component={Stats} />
  </Route>
</BrowserRouter>

The code above obviously won't work because:

Warning: You should not use <Route component> and in the same route; <Route component> will be ignored

Answers to similar questions on SO suggest to use wrapper components directly:

<BrowserRouter>
  <BaseLayout>
    <Route path="/index" component={Index} />
    <Route path="/about" component={About} />
  </BaseLayout>
  <AuthLayout>
    <Route path="/sign-in" component={SignIn} />
    <Route path="/sign-up" component={SignUp} />
  </AuthLayout>
  <DashboardLayout>
    <Route path="/stats" component={Stats} />
  </DashboardLayout>
</BrowserRouter>

Problem with this approach is that even that it renders a single screen, it also renders elements from the other layouts, i.e. if you're on the index page rendered inside the BaseLayout, you will see elements from the AuthLayout and DashboardLayout too. Which kinda makes sense because they are not wrapped in a Route.

Some people suggested to grab the content of all layouts and add them as siblings to the current Routes. However this is a mess to me. I do want to keep all layouts in separate files and only pass screens as children to them.


Solution

This is a rough draft of a potential layout structure:

<Header>
  <Route>
    <Route path={['/index', '/about']} component={HeaderComponent} />
    <Route path={['/sign-in', '/sign-up']} component={AuthHeaderComponent} />
  </Route>
</Header>
<Screens>
  <Route>
    <Route path="/index" component={BaseLayout(Index)} />
    <Route path="/about" component={BaseLayout(About)} />
    <Route path="/sign-in" component={AuthLayout(SignIn)} />
    <Route path="/sign-up" component={AuthLayout(SignUp)} />
    <Route path="/stats" component={DashboardLayout(Stats)} />
  </Route>
</Screens>
<Footer>
  <FooterComponent />
</Footer>

In this example the wrappers are HOCs so they can handle passing all props from the route down to the page component, but if you just wanted to do an inline wrapper you could use the render function:

<Route
  path="/index"
  render={routeProps => {
    return (
      <BaseLayout>
        <Index {...routeProps}/>
      </BaseLayout>
    );
  }}
/>

[edit] A sample Layout HOC (docs)

const withBaseLayout = WrappedComponent => {
  // any business logic required for the layout
  // layoutProps, style, etc...
  return (
    <BaseLayout {...layoutProps}>
      <WrappedComponent {...this.props} /> // these are all the passed in props
      // you can inject more props into Wrapped component as well
      // i.e. redux's connect or react-router-dom's withRouter HOCs
    </BaseLayout>
  );
}

// in index.js
export default withBaseLayout(Index);

// in route
<Route path="/index" component={Index} /> // already wrapped

Or directly as Component

const BaseLayoutHOC = WrappedComponent => {
  // any business logic required for the layout
  // layoutProps, style, etc...
  return (
    <BaseLayout {...layoutProps}>
      <WrappedComponent {...this.props} />
    </BaseLayout>
  );
}

// in route
<Route path="/index" component={BaseLayoutHOC(Index)} />


Answered By - Drew Reese
Answer Checked By - - Willingham (ReactFix Volunteer)
  • Share This:  
  •  Facebook
  •  Twitter
  •  Google+
  •  Stumble
  •  Digg
Newer Post Older Post Home

Featured Post

Is Learning React Difficult?

React is difficult to learn, no ifs and buts. React isn't inherently difficult to learn. It's a framework that's different from ...

Total Pageviews

Copyright © ReactFix