Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React router: route-based navbar content

I have a simple single-page React app setup with navbar, content and footer. Navbar itself consists of two sub-navbars: one that is same for every page, and the one that should change dynamically based on route (page-specific navbar).

So basically, I have one top-level component Container:

<Navbar>
  <Navbar.Main/>
  <Navbar.Page/>
</Navbar>
{this.props.children}
<Footer/>

and routes defined in App:

<Router history={browserHistory}>
  <Route component={Container}>
    <IndexRoute component={Home} />
    <Route path="/" component={Home} />
    <Route path="/contact" component={Contact} />
    <Route path="/about" component={About} />
    <Route path="*" component={NotFound} />
  </Route>
</Router>

While the page content will change within the {this.props.children} part, I'd like to change content of <Navbar.Page/> navbar component based on the route (Contact page should have Contact-specific navbar, etc.).

I know that I can easily achieve that by rendering page navbar within the page, but I'd like to keep rendering in the navbar itself.

like image 606
aL3xa Avatar asked Nov 17 '25 20:11

aL3xa


1 Answers

One way we are currently using in our project is to pass components props to Route component and do what you want to do.

<Router history={browserHistory}>
  <Route component={Container}>
    <IndexRoute component={Home} />
    <Route path="/" component={Home} 
       // here I added components, but the name can be anything actually
       components={{ navBarPage : SomeComponent }} 
       navBarPages={{ component : SomeComponent }}
    />
    <Route path="/contact" component={Contact} />
    <Route path="/about" component={About} />
    <Route path="*" component={NotFound} />
  </Route>
</Router>

So first We know we can pass props to routes but another thing is how to reach these props from components.

As you can put a debugger and search for your props in the parent Container component, you can see that there is a 'routes' property ( aka this.props.routes ) for your Container component.

But here is the dirty thing, you have to know how deep is the component relative to parent Router ( aka the component Container ), so that you can reach it.

For instance debug your Container component to see available props:

As I added components, navBarPages, I can reach these objects from Container as :

this.props.routes[0] // this is what you passed to Container

this.props.routes[1] // one level deeper is what I want 
this.props.routes[1]['navBarPage']
this.props.routes[1]['components']

Note that, naturally, as your route change your this.props.routes will change.

like image 57
FurkanO Avatar answered Nov 19 '25 08:11

FurkanO