aL3xa
aL3xa

Reputation: 36080

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.

Upvotes: 3

Views: 1488

Answers (1)

FurkanO
FurkanO

Reputation: 7298

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.

Upvotes: 2

Related Questions