skip to Main Content

I am using react-router@6 and have a Route that I used in V5. Routes of a vehicles which always accepts one parameter (:id = vehicle id). But also has a second parameter (:date = string in DD-MM-YYYY format that is optional):

<Route path='/vehicles/routes/:id/:date?'>
  <VehicleRoutesPage requiresRole={[1,2,3]} requiresAuth="vehicle_routes" />
</Route>

I am trying to convert this into react-router@6. It is working up to a point – meaning it will work only with ID but not with the optional date parameter. With the optional date parameter I am redirected to the not found page.

<Route path="/vehicles/routes/:id" element={<VehiclesRoutesPage />} />

This will get me to the not found page. Both with the optional date parameter and without it:

<Route path="/vehicles/routes/:id/:date?" element={<VehiclesRoutesPage />} />

This will always get me to the routes page but no parameters are ever red:

<Route path="/vehicles/routes/*" element={<VehiclesRoutesPage />} />

Mentioning all above (working or partially working) I am always getting error in the console:
GET http://localhost:3000/vehicles/routes/undefined 404 (Not Found)
Even with the simple :id only case where the page gets correctly displayed:
<Route path="/vehicles/routes/:id" element={<VehiclesRoutesPage />} />

It is worth to mention that my components are wrapped in withRouter HOC:

import {
  useLocation,
  useNavigate,
  useParams
} from 'react-router-dom'

function withRouter(Component: any) {
  function ComponentWithRouterProp(props: any) {
    let location = useLocation();
    let navigate = useNavigate();
    let params = useParams();
    return (
      <Component
        {...props}
        router={{ location, navigate, params }}
      />
    );
  }

  return ComponentWithRouterProp;
}

export default withRouter

This is so I can actually access location, params and navigate properties which I need.

I am pretty sure I am overlooking something but I am unable to see what am I doing wrong.

2

Answers


  1. Your routes should be of this form :

        <BrowserRouter>
          ...
            <Routes>
              ...
              <Route path="/vehicule" element={<Vehicule />}>
                <Route path="/vehicule/routes" element={<VRoutes />}>
                  <Route path="/vehicule/routes/:id" element={<Id />}>
                    <Route path="/vehicule/routes/:id/:date" element={<Date />} />
                  </Route>
                </Route>
              </Route>
            </Routes>
          ...
        </BrowserRouter>
    

    just replace dummy elements with your components.


    Use Outlet to render nested route, for example:

    import { Outlet } from "react-router-dom";
    
    export function Vehicule() {
      return (
        <div>
          <Outlet></Outlet>
        </div>
      );
    }
    

    and of course you can useParams in the nested routes:

    const {id,date} = useParams();
    

    Here is a codesandbox to test it out and let me know if something went wrong.

    Login or Signup to reply.
  2. I don’t see any particular issue with the route:

    <Route
      path="/vehicles/routes/:id/:date?"
      element={<VehiclesRoutesPage />}
    />
    

    What I suspect is the issue is that you are using an older version of react-router-dom@6. Optional path parameters were reintroduced to react-router-dom starting with v6.5.0. As of this posting v6.8.1 is the current version. Provided you bump your dependency to at least [email protected] the route with optional path parameters should function as you are expecting.

    Edit react-router-v6-how-do-i-set-up-route-path-with-multiple-id-some-optional

    enter image description here

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search