Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How not to render a parent route in React Router 6?

Tags:

react-router

<Route path="/exercises" element={List}>
    <Route path=":id" element={Exercise} />
</Route>

The urls:

/exercises

/exercises/15

When the user accesses /exercises they see a list of titles of exercises. They can click on the title and go to the exercise. When then go to e.g. /exercises/15 they should see that exercise.

The key point is that when the Exercise component renders we don't want the List component to render at all. They are different things.

The examples in the documentation seem to be about the case when e.g. you have a list of Messages and you still want to see that list when you render an individual Message. In such a case you would render the component for the Individual Message by using <Outlet> in Messages. The user sees the list of Messages and the individual message.

But in my case I just want the individual 'final' component to render.

So I think that from the React Router point of view this is not a nested route at all? On that basis I've tried:

<Route path="exercises" element={List} />
<Route path="exercises/:id" element={Exercise} />  

This works in fact. Is this the correct way to do it?


1 Answers

Yes, you can create List component as a layout component that renders some UI and an Outlet to render nested Route components.

<Route path="/exercises" element={<List />}>
  <Route path=":id" element={<Exercise />} />
</Route>

This will always render the layout List component when it matches.

If you are wanting to render components individually then you can either use two separate, unrelated routes.

<Route path="/exercises" element={<List />} />
<Route path="/exercises/:id" element={<Exercise />} />

Or render both into a layout component. Use an index route to match and render a route when a path exactly matches the layout path.

const ExerciseLayout = () => {
  // any common business logic/state/etc...

  return (
    <div /* any common layout styling, etc.... */ >
      <Outlet />
    </div>
  );
};

<Route path="/exercises" element={<ExerciseLayout />}>
  <Route index element={<List />} />
  <Route path=":id" element={<Exercise />} />
</Route>

This is useful if List and Exercise routes are always rendered together and you want to atomically move them around, or if you have some common logic or styling you want to share between the "/exercise" routes. Or you can just simply render the Outlet for them as a minimum.

<Route path="/exercises" element={<Outlet />}>
  <Route index element={<List />} />
  <Route path=":id" element={<Exercise />} />
</Route> 
like image 186
Drew Reese Avatar answered Nov 18 '25 20:11

Drew Reese



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!