React-router: "withRouter" doesn't rerender elements when state is changed

Created on 10 Mar 2017  路  4Comments  路  Source: ReactTraining/react-router

Version

4.0.0-beta.8
Node: 6.6.9

Test Case

Ping me if you really want one. I can probably deploy something on heroku since this test depends on the browser url and I don't have access to it in jsbin.

Steps to reproduce

  1. Create an example app with BrowserRouter
  2. Create a component and use jsx to show { this.props.location.pathname } in the html.
  3. Use withRouter on the component and render.

Expected Behavior

I expect to see the component rerender on a history state change, but this doesn't seem to happen.

Actual Behavior

Component does not rerender. You can see this by adding a console.log in the render or using the jsx method described above.

Current Fix

This seems to work when rolling back react-router and react-router-dom to 4.0.0-beta.6. The withRouter then does have history context and works as intended. I'm not sure but it seems as if beta.8 introduced a bug.

Most helpful comment

This is really confusing.

I'm constantly hitting this issue and the workarounds seem to be ugly. I often have an intermediate component which implements shouldComponentUpdate via PureComponent and I have go and make it aware of the router even if it does not use the router at all.

Why the withRouter HOC or the Route component cannot directly listen to the location changes? Bit like connect() in react-redux listens to the store changes via context. It does not break when put as a child of an pure component.

I also find the blocked-updates.md documentation weird because the proposed solution is to add withRouter but it is itself affected the by the issue.

All 4 comments

You are either using shouldComponentUpdate (directly or indirectly through something like react-redux or mobx-react) or React.PureComponent. These are blocking your application from fully updating on location changes. Please see the blocked updates guide for more information.

@pshrmn can we reopen this and check out PR #4684. I'd love to add to the documentation about this issue. It was pretty non-intuitive but after your explanation, I think it would be worth adding to the docs.

This is really confusing.

I'm constantly hitting this issue and the workarounds seem to be ugly. I often have an intermediate component which implements shouldComponentUpdate via PureComponent and I have go and make it aware of the router even if it does not use the router at all.

Why the withRouter HOC or the Route component cannot directly listen to the location changes? Bit like connect() in react-redux listens to the store changes via context. It does not break when put as a child of an pure component.

I also find the blocked-updates.md documentation weird because the proposed solution is to add withRouter but it is itself affected the by the issue.

It's impossible for me to make every pure component aware of the react-router so I made following workaround:

class ListeningRoute extends React.Component {
    componentWillMount() {
        this.unlisten = this.props.history.listen(location => {
            this.setState({location});
        });
    }

    componentWillUnmount() {
        this.unlisten();
    }

    render() {
        return <Route {...this.props}  location={this.state.location} />;
    }
}
ListeningRoute = withRouter(ListeningRoute);

This ListeningRoute component works exactly like the default Route but it does render when it's a child of an pure component.

This works because the Route component can get the location pathname from the location prop as well as from the router context:

https://github.com/ReactTraining/react-router/blob/a3362060a9e349b3356eec548b03af13b9c37cc8/packages/react-router/modules/Route.js#L56

UPDATE: Let's continue in https://github.com/ReactTraining/react-router/issues/4671

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ArthurRougier picture ArthurRougier  路  3Comments

imWildCat picture imWildCat  路  3Comments

Waquo picture Waquo  路  3Comments

maier-stefan picture maier-stefan  路  3Comments

yormi picture yormi  路  3Comments