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

Monday, November 14, 2022

[FIXED] How can I create a subrouter with React Router v6?

 November 14, 2022     javascript, react-router, react-router-dom, reactjs, typescript   

Issue

Here is my current React Router implementation:

const router = createBrowserRouter([
    {
      path: "/",
      element: (
        <Page activeNav="home" >
          <Home />
        </Page>
      )
    },
    {
      path: "/about",
      element: (
        <Page activeNav="about" >
          <About />
        </Page>
      )
    },
    {
      path: "/blog",
      element: (
        <Page activeNav="blog">
          <Blog />
        </Page>
      )
    },
    {
      path: "/blog/:postName",
      element: (
        <Page activeNav="blog" >
          <Post />
        </Page>
      ),
      loader: ({ params }) => params.postName
    },
    {
      path: "/chess",
      element: <ChessRouter />
    }
  ])

The last route, /chess is of importance. I am looking to define routes such as /chess/play, /chess/login, /chess/register, etc. My initial idea was to just put another Router as the element for the /chess path and then all those paths would be routed from there. However, that throws an error saying:

You cannot render a <Router> inside another <Router>. You should never have more than one in your app.

I also tried using the children property on the /chess route but this does not render anything when I go to /chess/play etc.

What is the correct way of implementing subpaths (not sure of the correct word for it)?


Solution

It is correct that you cannot render a router component within another router component as this is an invariant violation. You need only one router and routing context per React app.

To render sub-routes on "/chess" then there are two options:

  1. Render nested routes in the routes configuration declaration. This requires the ChessRouter component to render an Outlet component for nested routes to render their element content into. Nested routes will be able to use the new RRDv6.4 Data APIs.

    const router = createBrowserRouter([
      ...,
      {
        path: "/chess",
        element: <ChessRouter />,
        children: [
          ...,
          {
            path: "play",
            element: <ChessPlay />
          },
          ... other chess sub-rotues
        ],
      }
    ]);
    
    const ChessRouter = () => {
      ...
    
      return (
        ...
        <Outlet />
        ...
      );
    };
    
  2. Render a root route with trailing wildcard ("*") character that allows descendent routes to also be matched. This allows the ChessRouter component to render descendent routes, i.e. a Routes component with a set of Route components. Descendent routes will not be able to use the RRDv6.4 Data APIs.

    const router = createBrowserRouter([
      ...,
      {
        path: "/chess/*",
        element: <ChessRouter />,
      }
    ]);
    
    const ChessRouter = () => {
      ...
    
      return (
        ...
        <Routes>
          ...
          <Route path="/play" element={<ChessPlay />} />
          ... other chess sub-rotues
        </Routes>
        ...
      );
    };
    


Answered By - Drew Reese
Answer Checked By - - David Marino (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