Reputation: 23
So, I'm not sure if I should've structured my app different or if I'm doing something fundamentally wrong. I'm a bit confused, but let's explain first things first.
In the first navigation level, there are 4 pages - and for every page, there is a detail page.
The article category pages are exactly the same. They all hold a list (<ul><li><Link></Link></li><li>...</ul>
) of 10-20 articles, so I actually just created one component, the article category component.
To make this work, the main navigation of the app holds <Link>
's which have a param called page
passed to the article category component. Depending on this parameter, the view looks for the articles in an array and uses another component to render them as a list.
The article array itself holds the name of the the article and the parameter article name, f.e. this-is-an-article. I'm passing the article name parameter to the detail component which looks, depending on this and the page parameter, for the correct article.
Okay, so I hope this is clear. Now, this is my react-router configuration:
export default (
<Route path="/" handler={App}>
{/* Home */}
<DefaultRoute name="home" handler={Home}/>
{/* Page */}
<Route name="category" path=":category" handler={Category}>
<Route name="category.article" path=":article" handler={Article} />
</Route>
{/* Not found */}
<NotFoundRoute handler={NotFound} />
</Route>
);
.. but this doesn't work. If I click on an article link which has the correct parameters, nothing happens - well, the URL changes, but nothing else.. and the navigation menu item stays active, which is good. I at least know the parameters are correct because when I change my route confgiruation below /* Page */
to this:
<Route name="category" path=":category" handler={Category} />
<Route name="category.article" path=":category/:article" handler={Article} />
it works, but in my main navigation, the naivgation item isn't active anymore when I'm on an article (detail) page, I guess because it's not a child route anymore, so the configuration above this should be the correct one, but it doesn't work..
Below, there are the relevant components and their code + the content array/object. Mind you, the code shown is without any import's (I'm using ES6 with Babel through Webpack), but of course there are some.
Article component (renders the article itself)
let Article = React.createClass({
getInitialState() {
return {
article: this.props.params.article,
category: this.props.params.category
}
},
componentWillReceiveProps(nextProps) {
this.setState({
article: nextProps.params.article,
category: nextProps.params.category
})
},
render() {
let content = this._getContent();
return (
<div className="page_content page_content-article">
<ArticleHeader />
{content}
</div>
)
},
_getContent() {
let item;
for(item of ContentStore[this.state.category]) {
if(item.name === this.state.article) {
return item.content;
}
}
}
});
Category component (renders the article list with the ArticleList component which just renders with the category and article params and is the same for each category)
let Index = React.createClass({
getInitialState() {
return {
category: this.props.params.category
};
},
componentWillReceiveProps(nextProps) {
this.setState({
category: nextProps.params.category
});
},
render() {
return (
<div className={'page_content page_content-' + this.state.category}>
<ArticleList articles={this._getArticles()} category={this.state.category} />
</div>
)
},
_getArticles() {
return ContentStore[this.state.category];
}
});
App component
let App = React.createClass({
render() {
return (
<div className="page">
<RouteHandler />
<Navigation />
</div>
)
}
});
PageStore (Example of the data - this renders the main navigation)
PageStore: [
{
id: 1,
title: 'Home',
iconClass: 'home',
linkTo: 'home',
params: null
},
{
id: 2,
title: 'Category 1',
iconClass: 'foo',
linkTo: 'category',
params: {
category: 'foo',
}
},
...
]
ContentStore (example of the data - this renders the article lists and the detail view as it has it's content)
ContentStore: {
// "foo" is the category name
foo: [
{
id: 1,
name: 'article-1',
linkText: 'Article 1',
content: (
<div>
lorem ipsum...
</div>
)
},
]
}
I have two questions:
I also ask if I actually should do this because well.. I never see nested routes where both, the parent and the child, have props. Maybe this is actually a bad thing to do.. I'm not sure. If you need any more information, I'm happy to provide it and thanks you in advance.
Upvotes: 2
Views: 173
Reputation: 2402
I've never seen the use of the :
before the path, I even checked the docs to see if there was an example and couldn't find one, maybe I missed it, the :
is used for parameters as far as I know. Anyhow, try this:
<Route path="/" handler={App}>
{/* Home */}
<DefaultRoute name="home" handler={Home}/>
{/* Page */}
<Route path="category" handler={Category}>
<Route path="category/article" handler={Article} />
</Route>
{/* Not found */}
<NotFoundRoute handler={NotFound} />
</Route>
See if that gets the pages working for now and than go from there.
Upvotes: 0