Reputation: 5759
I'm building a simple react app with a sidebar. from it, I want to swap out the various categories of the app.
My router looks like this:
<Route path={path} component={App}>
<IndexRoute component={HomeView} />
<Route path="/" component={HomeView} />
<Route path="/manage" component={LoggedInView} />
<Route path="/search/:topic" component={SearchView} />
<Route path="/c/:category" component={CategoryView} />
<Route path="*" component={ErrorView} type="404"/>
</Route>
In the sidebar I have a link like this:
<Link to={{ pathname: '/c/'+el.urlkey}} activeClassName="active"{el.title}</Link>
Finally in the CategoryView I have this variable:
let queryParam = this.props.params.category;
When I click the Link, the url in the urlbar changes, but the category doesn't. When I click it again, the category changes as well.
If I log the 'queryParam ', I see that the first time I click, it returns the same value. only after the second click does it change.
Why isn't it changing on the first click? I've also tried routing programmatically using
this.props.router.push(url);
But the issue still occurs. Any help is greatly appreciated!
This is the code for the Categoryview
@pureRender
class Category extends Component {
constructor(props) {
super(props);
this.state = {
activeCategoryName: '',
activeCategory: {},
availableTopics: {},
...
};
}
componentWillReceiveProps() {
this.showCategory();
}
componentWillMount(){
this.showCategory();
}
showCategory(){
const self = this;
let queryParam = this.props.params.category;
const availableCategories = this.props.categories;
let matched = false;
const count = availableCategories.length - 1;
if(count === -1){
this.setState({
notFound: true
});
} else {
filter(availableCategories, function (el, index) {
const categoryTitle = el.urlkey.toLowerCase();
const activeLocale = self.props.activeLocale;
let title = null;
if (queryParam !== undefined) {
title = queryParam.toLowerCase();
}
Upvotes: 2
Views: 3845
Reputation: 1593
Pass your props to showCategory function
so that it can update the new value whenever a new props arrive into the component
componentWillReceiveProps(nextProps) {
this.showCategory(nextProps);
}
componentWillMount(this.props){
this.showCategory(this.props);
}
showCategory(props){
const self = this;
let queryParam = props.params.category;
const availableCategories = props.categories;
let matched = false;
const count = availableCategories.length - 1;
if(count === -1){
this.setState({
notFound: true
});
} else {
filter(availableCategories, function (el, index) {
const categoryTitle = el.urlkey.toLowerCase();
const activeLocale = self.props.activeLocale;
let title = null;
if (queryParam !== undefined) {
title = queryParam.toLowerCase();
}
if(categoryTitle === title && el.language === activeLocale){
matched = true;
self.setState({
activeCategoryName: categoryTitle,
activeCategory: el,
notFound: false,
isLoading: false,
isEmpty: false
});
} else if(index === count && !matched){
self.setState({
isEmpty: true,
isLoading: false
});
}
});
}
}
Upvotes: 1
Reputation: 13621
The reason you're seeing the old data when you click the second time, is because componentWillReceiveProps executes before this.props
is updated with that information. Update the method to do this instead:
componentWillReceiveProps(nextProps) {
this.showCategory(nextProps);
}
showCategory(props) {
let queryParam = props.params.category;
// etc
}
In terms of the first one not showing up, try passing this.props
(with the changes above) in a componentDidMount instead of componentWillMount. I realize this causes a new render to run, but I wonder if the props aren't initialized yet. If that doesn't fix it, I think you need to debug the details in your filter function, and see if setState is being called.
Upvotes: 4