damjuve
damjuve

Reputation: 354

React router v6 param and nested routes

I would like to use some nested routes with params in the middle

The routes i would like to be able to reach are :

/foo/:id/bar1
/foo/:id/bar2
/foo/:id/bar3

My routing is

<Route path="foo" element={<Foo />}>
  <Route path=":id">
     <Route path="bar1" element={<Bar1 />}>
     <Route path="bar2" element={<Bar2 />}>
     <Route path="bar3" element={<Bar3 />}>
  </Route>
</Route>

(Foo does have an <Outlet /> component).

But when i access /foo/42/bar1 i got No routes matched location

Also I would like to be able to access /foo without id and nested routes. But when I do so i also got No routes matched location.

Finally I would like to define /foo/:id/prono as index, that means /foo/:id should redirect to it.

How can I achieve all of this ?

Upvotes: 1

Views: 4566

Answers (2)

Drew Reese
Drew Reese

Reputation: 202605

I don't see any overt issues with your code, and copy/pasting it into a running codesandbox doesn't reproduce the errors you describe.

Even so, here's a routing suggestion:

<Route path="foo" element={<Foo />}>
  <Route path=":id">
    {/* Index route redirects to "prono" */}
    <Route index element={<Navigate to="prono" replace />} />

    <Route path="bar1" element={<Bar1 />} />
    <Route path="bar2" element={<Bar2 />} />
    <Route path="bar3" element={<Bar3 />} />
    <Route path="prono" element={<Prono />} />

    {/* Unknown paths redirect to index route */}
    <Route path="*" element={<Navigate to="." replace />} />
  </Route>
</Route>

Edit react-router-v6-param-and-nested-routes

Upvotes: 1

Dave
Dave

Reputation: 7717

Code Sandbox

I only show the id in Bar1, but you can do the same in the other components to see where you came from. And maybe <Route index element={<Prono />} /> should just Navigate to 'Promo'...

import "./styles.css";
import {
  BrowserRouter,
  Routes,
  Route,
  Navigate,
  Outlet,
  useParams,
  Link
} from "react-router-dom";

const Foo = () => (
  <div>
    I am the foo component.
    <div>
      <Link to="/foo"><a>goto foo</a></Link><br />
      <Link to="43"><a>goto 43</a></Link><br />
      <Link to="43/bar1"><a>goto 43/Bar1</a></Link><br />
      <Link to="43/bar2"><a>goto 43/Bar2</a></Link>
    </div>
    <Outlet />
  </div>
);

const Prono = () => <div>I am Prono, hear me roar.</div>;
const Bar1 = () => {
  const { id } = useParams();
  return (
    <>
      <div>I am the bar1 component.</div>
      <div>My id is {id}</div>
    </>
  );
};
const Bar2 = () => <div>I am the bar2 component.</div>;
const Bar3 = () => <div>I am the bar3 component.</div>;

function App() {
  return (
    <Routes>
      <Route path="/" element={<Navigate to={"/foo"} replace />} />
      <Route path="foo" element={<Foo />}>
        <Route path=":id">
          <Route index element={<Prono />} />
          <Route path="prono" element={<Prono />} />
          <Route path="bar1" element={<Bar1 />} />
          <Route path="bar2" element={<Bar2 />} />
          <Route path="bar3" element={<Bar3 />} />
        </Route>
      </Route>
    </Routes>
  );
}

const AppWithRouter = () => (
  <BrowserRouter>
    <App />
  </BrowserRouter>
);
export default AppWithRouter;

Upvotes: 0

Related Questions