utg.tdawg
utg.tdawg

Reputation: 358

How to match multiple sibling routes with React Router V6?

I am trying to implement tabs navigation using React router v6. To do so, I need the following rendering pattern:

<Tabs /> is a navigation bar that allows users to navigate between tab panels A and B. It needs to be aware of currentTab so that it can change the corresponding tab's color. It also needs to be constantly rendered even as the user navigates across different tab panels.

However, my current code only renders <TabPanelA /> when the URL is /tabsDemo/a because /tabsDemo/a is more specific than /tabsDemo/:currentTab

function App() {
  return (
    <Routes>
      <Route path="tabsDemo" element={<Outlet />}>
        <Route path=":currentTab" element={<Tabs />} />
        <Route path="a" element={<TabPanelA />} />
        <Route path="b" element={<TabPanelB />} />
      </Route>
    </Routes>
  );
}

How can I achieve the aforementioned rendering pattern?

Upvotes: 1

Views: 920

Answers (2)

Drew Reese
Drew Reese

Reputation: 203476

The most trivial method would be to render the Tabs component in each place you want.

Example:

function App() {
  return (
    <Routes>
      <Route path="tabsDemo" element={<Outlet />}>
        <Route path=":currentTab" element={<Tabs />} />
        <Route
          path="a"
          element={(
            <>
              <Tabs />
              <TabPanelA />
            </>
          )}
        />
        <Route
          path="b"
          element={(
            <>
              <Tabs />
              <TabPanelB />
            </>
          )}
        />
      </Route>
    </Routes>
  );
}

It sounds like you want to render the Tabs component regardless. For this you should convert it into a layout route that renders the Outlet.

Example:

const Tabs = () => {
  ... tabs logic ...

  return (
    ...
    <Outlet />
    ...
  );
};

...

function App() {
  return (
    <Routes>
      <Route path="tabsDemo" element={<Tabs />}>
        <Route path="a" element={<TabPanelA />} />
        <Route path="b" element={<TabPanelB />} />
        <Route
          path=":currentTab"
          element={/* some component to read the `currentTab` param ??? */}
        />
      </Route>
    </Routes>
  );
}

Upvotes: 1

mahan
mahan

Reputation: 15035

Try this.

<Route path="/tabsDemo" element={<Tabs />}>
   <Route path="/a" element={<TabPanelA />} />
   <Route path="/b" element={<TabPanelB />} />
</Route>

See more:

https://reactrouter.com/docs/en/v6/components/route#routes-and-route

Upvotes: 0

Related Questions