Reputation: 10905
I'm trying to figure out how to properly nest routes inside the homepage. Here's my Router:
var appRouter = (
<Router history={ hashHistory }>
<Route path="/" component={ Navbar }>
<IndexRoute component={ Homepage }/>
<Route path="items" component={ Homepage }>
<Route path=":item" component={ ItemShow }/>
</Route>
<Route path="nothome" component={ NotHome }/>
</Route>
</Router>
)
Having an IndexRoute and Route that both point to Homepage doesn't seem optimal, but it gives me the behavior I'm looking for. Here's my whole project (I wrote this just to illustrate this point).
//React
var React = require("react");
var ReactDOM = require("react-dom");
//Router
var ReactRouter = require('react-router')
var Router = ReactRouter.Router
var Route = ReactRouter.Route
var IndexRoute = ReactRouter.IndexRoute
var hashHistory = ReactRouter.hashHistory
var Link = ReactRouter.Link
var items = [1, 2]
var Navbar = React.createClass({
render(){
return(
<div>
<Link to="/"><h1>Navbar</h1></Link>
{this.props.children}
</div>
)
}
})
var Homepage = React.createClass({
render(){
return(
<div>
<h2>This is the homepage</h2>
<ItemList/>
<Link to="/nothome">Another page</Link>
{this.props.children}
</div>
)
}
})
var ItemList = React.createClass({
render(){
return(
<ul>
{items.map( item => {
return <Item key={item} id={item}></Item>
})}
</ul>
)
}
})
var Item = React.createClass({
handleClick(){
hashHistory.push("items/" + this.props.id)
},
render(){
return(
<li onClick={this.handleClick}>Item {this.props.id}</li>
)
}
})
var ItemShow = React.createClass({
render(){
return(
<div>
You clicked on item {this.props.params.item}
</div>
)
}
})
var NotHome = React.createClass({
render(){
return(
<h2>This is not the homepage</h2>
)
}
})
var appRouter = (
<Router history={ hashHistory }>
<Route path="/" component={ Navbar }>
<IndexRoute component={ Homepage }/>
<Route path="items" component={ Homepage }>
<Route path=":item" component={ ItemShow }/>
</Route>
<Route path="nothome" component={ NotHome }/>
</Route>
</Router>
)
document.addEventListener("DOMContentLoaded", ()=>{
ReactDOM.render(appRouter, document.getElementById("root"))
})
Another option would be to put a Homepage component at the top of my ItemShow component and not nest the routes, but that seems just as bad if not worse.
It seems like there must be a preferable way to get this behavior. What is it?
Upvotes: 0
Views: 313
Reputation: 2067
Looking for your code, it seems that you don't really need to have this "items" route, since both "/" and "/items" render the same component (<Homepage>
).
So, if you want to avoid having two "Homepage
" declaration, you can redirect your user to "items", whenever they go to "/". You can do that by using <IndexRedirect>
or <Redirect>
or onEnter
hook.
More information about the hook:
https://github.com/reactjs/react-router/blob/v2.5.2/docs/guides/IndexRoutes.md#index-redirects
If you really want to be able to access those two routes pointing to the same component, maybe you don't have to change anything. But, in your case, I would have a "Homepage" (even with some dummy info) and a "Items Homepage", and it would avoid the "Homepage" repetition.
BTW, just as a tip, I would rename your <NavBar>
to "<App>
" or something like that, since it would be better to understand your code!
Upvotes: 1