React-router: Nested BrowserRouter

Created on 28 Jun 2017  路  5Comments  路  Source: ReactTraining/react-router

Bug

Version

4.0.0

Test Case

https://codepen.io/anon/pen/NgXNxE?

Steps to reproduce

  1. Click "Home" link
  2. Click "Exchange" link
  3. Click "Message link"
  4. Click again to "Exchange" link

Expected Behavior

View "Subroute Home page." header
Address bar also changes

Actual Behavior

View "Subroute message." header
Don't follow to SubrouteIndex
Addressbar not handle route change

All 5 comments

You shouldn't nest BrowserRouter ever. If you need an isolated Router, use MemoryRouter.

But how implement nested routing with handling it in address bar? Why my realization is bad?

You can't do that. The top level BrowserRouter is going to create a history instance that will listen to pushState events. There is no way to do what you're looking to do in any version of React Router.

Thx a lot!

Having a nested BrowserRouter (or equivalent) may be a common requirement in large applications that are separated in to modules.

In our case, this is solely so that:

  • We are able to set a basepath on a descendent of a BrowserRouter, that affects the behaviour of descendent react-router components
  • React Router applications can be distributed as modules and live within parent applications that also use React Router

I looked in to the issues described by @timdorr above and think I have a solution.

I created a NestedBrowserRouter component that uses the parent router's history but adds a basepath:

https://github.com/penx/nested-browser-router

I have put a demo usage here:

https://codesandbox.io/s/q4l9vo1m89

    <BrowserRouter>
      <React.Fragment>
        <h1>Application</h1>
        <Link to="/">Home</Link> | <Link to="/sub">Sub app</Link> |{" "}
        <Link to="/sub/sub">Sub sub</Link>
        <Switch>
          <Route exact path="/" render={() => <h2>Home</h2>} />
          <Route
            path="/sub"
            render={() => (
              <NestedBrowserRouter basename="sub">
                <>
                  <h1>Sub app</h1>
                  <Link to="/">Sub Home</Link> | <Link to="/sub">Sub Sub</Link>
                  <Switch>
                    <Route exact path="/" render={() => <h2>Sub Home</h2>} />
                    <Route exact path="/sub" render={() => <h2>Sub Sub</h2>} />
                  </Switch>
                </>
              </NestedBrowserRouter>
            )}
          />
        </Switch>
      </React.Fragment>
    </BrowserRouter>

Caveats:

  • This requires React Router @4.4 which is still in beta
  • I've only proven a basic use case here, would be interested in feedback and to hear if this works for all use cases. We are planning to use this in production on a large scale, modularised React application that lives across multiple repositories.
  • I'm not yet sure how to link from the sub app/router back up to the parent app/router
Was this page helpful?
0 / 5 - 0 ratings

Related issues

maier-stefan picture maier-stefan  路  3Comments

nicolashery picture nicolashery  路  3Comments

misterwilliam picture misterwilliam  路  3Comments

alexyaseen picture alexyaseen  路  3Comments

ackvf picture ackvf  路  3Comments