Search code examples
javascriptreactjsreact-routerreact-router-dom

Wrap your <Route> in a <Routes> Error but Route is wrapped


I am converting my old code to react-router-dom version 6 and I am stuck with this.

This is my code in react-router-dom v5:

const AddRoute = ({ usergroups, ...props }) => (
  usergroups.length > 0
    ? <Route {...props} />
    : <Route component={NotFound} />
)
<Switch>
  <AddRoute
    usergroups={userGroups.files}
    exact
    path="/some/path/add"
    render={(props) => (
      <Name {...props} services={services} view={true} />
    )}
  />
</Switch>;

and this is how I converted it to version 6:

const AddRoute = ({ usergroups, ...props }) => (
  usergroups.length > 0
    ? <Route {...props} /> 
    : <Route element={<NotFound />} />
);
<Routes>
  <Route path="/some/path/add" 
    element={ <AddRoute usergroups={userGroups.metricprofiles} 
      element={<Name services={services} view={true} />} 
      />} 
  />
</Routes>

and it didn't work so I tried:

<Routes>
  <Route
    path="/some/path/add"
    element={<AddRoute usergroups={userGroups.files} />}
  >
    <Route element={<Name services={services} view={true} />} />
  </Route>
</Routes>

In both cases I am getting this error router.js:269 Uncaught Error: A <Route> is only ever to be used as the child of <Routes> element, never rendered directly. Please wrap your <Route> in a <Routes>. Why is this happening even though I wrapped the code in <Routes>?

Can I even use AddRoute like I did?


Solution

  • The error is informing you that the Route components that AddRoute renders must also be wrapped in a Routes component.

    const AddRoute = ({ usergroups, ...props }) => (
      usergroups.length > 0
        ? <Route {...props} />             // <-- this Route
        : <Route element={<NotFound />} /> // <-- and/or this Route
    );
    

    Refactor the code to not render these Route components and render the content directly.

    Example:

    const AddRoute = ({ element, usergroups }) => usergroups.length > 0
      ? element
      : <NotFound />;
    

    This will allow the first routing implementation to work:

    <Routes>
      <Route
        path="/some/path/add" 
        element={(
          <AddRoute
            usergroups={userGroups.metricprofiles} 
            element={<Name services={services} view />}
          />
        )} 
      />
    </Routes>
    

    If you prefer the second routing implementation:

    <Routes>
      <Route element={<AddRoute usergroups={userGroups.files} />}>
        <Route
         path="/some/path/add"
         element={<Name services={services} view />}
       />
      </Route>
    </Routes>
    

    Then AddRoute should be rewritten to be a layout route component, e.g. it renders an Outlet for the nested route content.

    import { Outlet } from 'react-router-dom';
    
    const AddRoute = ({ usergroups }) => usergroups.length > 0
      ? <Outlet />
      : <NotFound />;