1

In React Router v6, I'm trying to create a dynamic SubHeader component that changes based on a particular route or route param. For context, here's a contrived setup:

export const App = () => {
  return (
    <BrowserRouter>
      <Header>
        <TopHeader />
        <DynamicSubHeader /> // <-- here
      </Header>
      <Routes>
        <Route path="products" element={<Products />} />
        <Route path='product/:id/*' element={<ProductDetail />} >
          <Route path="price" element={<ProductDetailPrice />} />
        </Route>
      </Routes>
    </BrowserRouter>
  )
}

I'd like to update <DynamicSubHeader /> with different content when navigating between /products, /products/:id and even /products/:id/price

Inside <DynamicSubHeader />, I've tried to use the useParam hook provided by react-router-dom, but it just returns null or the data doesn't persist. It seems you can only use useParam when it's nested inside the <Routes> component.

I've also tried using the useLocation hook to listen for route change and manually setting state there, but it doesn't persist either.

For the time being, I've treated <Header /> as a Layout-component that I've placed in each route. Am I using React Router wrong? Otherwise, any suggestions on how to approach this?

new Q Open Wid
  • 2,225
  • 2
  • 18
  • 34
binhxn89
  • 109
  • 1
  • 10
  • Check this post. It will help you achieve what you want to: https://stackoverflow.com/questions/52684017/react-router-v4-nested-match-params-not-accessible-at-root-level/52752990#52752990 – Shubham Khatri Apr 30 '20 at 06:53
  • @ShubhamKhatri Unfortunately, the post is referring to v4, which does not carry over the same API to v6. There is, however, a useMatch hook that I'm trying to play around with. – binhxn89 May 01 '20 at 16:14
  • Yes, but the logic still remains the same. You cannot get a match value in the component that actually is at a level up than the actuall nested matched Route – Shubham Khatri May 01 '20 at 16:15

1 Answers1

1

To access your URL data try to use the match object with this.props.match inside your <DynamicSubHeader /> component.

This is how it looks on a sample edit route:

//$> console.log(this.props.match)
{
  isExact: true
  params:
    id: "5tkd6w"
    __proto__: Object
  path: "/streams/edit/:id"
  url: "/streams/edit/5tkd6w"
  __proto__: Object
}

Once you've got the id you can perform almost any operation and by getting the full URL you can determine other parts of your subheader content.

Leonardo Viada
  • 373
  • 3
  • 13