Simpleton
Simpleton

Reputation: 6415

Re-using the same component twice with react-router

I have a react class called MainContainer which displays some content. It has a child, SidebarContainer that lists a bunch of links. I render my main container and by default load the first piece of content using a default ID of 1 as a fallback if there is no param value in the URL:

var MainContainer = React.createClass({
  getInitialState: function() {
    return {
      selectedContent: this.props.params.slug || 1
  },

  componentWillReceiveProps: function(nextProps, nextState) {
    this.setState({
      selectedContent: this.props.params.slug || 1
    });
  },
}

The SidebarContainer component has a Link selector:

<Link to={content.slug}>
  {content.title}
</Link> 

When I click on the link, the browser's URL visibly changes, but nothing else happens. When I click again, the correct content renders. However, when I copy-paste a url with a specified param, it renders the correct content first time around.

My ReactDOM render method has the following react-router config:

ReactDOM.render((
  <Router>
    <Route path="/" component={MainContainer}/>
    <Route path="/content/:slug" component={MainContainer}/>
  </Router>
), document.getElementById('react-app'));

Am I using the componentWillReceiveProps lifecycle method incorrectly?

Upvotes: 0

Views: 1629

Answers (3)

Michael Rasoahaingo
Michael Rasoahaingo

Reputation: 1089

It's strange to use internal state, while you can directly access to this.props.slug anywhere inside of your component.

By the way, may be there's something missing on your router? the browserHistory?

import {browserHistory} from 'react-router'

<Router history={browserHistory}>
    ...
</Router>

Upvotes: 0

Manolo Santos
Manolo Santos

Reputation: 1913

An effective way to force updating a page after navigation, consists of assigning a key to the page component based on the router parameter. This way, if you navigate to the same page with a different parameter, react will unmount the previous one and mount the new one.

This trick can save you from having to reset the components' internal state manually and prevent some bugs for having a stale state from the previous page.

Upvotes: 0

Thiago Murakami
Thiago Murakami

Reputation: 995

Inside componentWillReceiveProps, shouldn't you use nextProps instead of this.props?

this.setState({
      selectedContent: nextProps.params.slug || 1
});

Upvotes: 5

Related Questions