kvn
kvn

Reputation: 2300

React force re-mount component on route change

How can I re-mount a component on route change when using the same component for both the routes?

Here is my code.

routes.jsx

<Router history={browserHistory}>
  <Route path="/" component={Home} />
  <Route path="/foo/:fooId" component={Home} />
</Router>

I have a conditional check in Home component for fooId, which renders the JSX accordingly.

<Link to="/foo/1234">fooKey</Link>

At the moment, when clicked on fooKey the route changes and the render function in Home component is re-triggered but is not mounted again.

I went through other answers which mentioned componentWillReceiveProps, but I have a lot of config in the constructor and I don't want to be moving all of that config to componentWillReceiveProps.

Please comment if more information is needed.

Upvotes: 3

Views: 13146

Answers (3)

Lafi
Lafi

Reputation: 1342

If you need to force remounting a Component on every routing match you could achieve it by the key property unless you're knowing what you're doing:

<Route
  exact
  path={'some path'}
  render={props => <RemountAlways key={Date.now()} {...props} />}
/>

key={Date.now()} this key property will force react to remount every time.

Note: componentWillReceiveProps is bad news in react.

Upvotes: 13

Kyle Richardson
Kyle Richardson

Reputation: 5645

So you're not going to want to un-mount and re-mount your component every time your query string changes. Change your routes to this:

<Router history={browserHistory}>
  <Route path="/" component={Home} />
</Router>

Wrap your <Home /> component with the withRouter HoC provided by React Router. Once you've done that, ({ match, history, location }) will be available in the <Home /> component. In your componentWillRecieveProps lifecycle hook you can perform any logic that requires query strings on props.location.search to produce the results you desire.

Upvotes: 3

Eugene Tsakh
Eugene Tsakh

Reputation: 2879

Apparently you're doing something wrong if you need to force re-mount. In general you should react on componentWillReceiveProps:

class DumbComponent extends React.Component {
  constructor(props) {
    super(props);

    this.state = this.propsToState(this.props);
  }

  componentWillReceiveProps(nextProps) {
    this.setState(this.propsToState(nextProps));
  }

  propsToState(props) {
    // place all of your state initialization dependent logic here
    return {
      foo: props.foo,
    };
  }

  render() {
    return <div>{this.state.foo}</div>
  }
}

Upvotes: 0

Related Questions