4.0.0
https://github.com/ralphsmith80/react-router-and-redux
Run the app enter text in the input and press enter key. Note that the ThirdView text is not rendered as expected. If you refresh the page it will be rendered, but it will not be removed once you navigate to a new route, Home or FirstView links.
Additionally I had to add withRouter to App.js which just seems plain weird.
The Route should update even when using react-redux.
I'm still trying to nail this all down in my larger application, but from the example app I'm providing it appears that every component that gets wrapped in a connect function needs to also be wrapped in a withRouter function.
I'm working on updating from 4.0.0-alpha.6 and this is working with the alpha version.
I'm not using redux to store my routing although I did try that out just as a sanity check, but that did not fix the issue.
I have not used a previous version of react-router so I don't know if it should play with react-redux even if I'm not trying to make them play together. Seems like an issue if they can't work independently in the same app.
@ralphsmith80
"it appears that every component that gets wrapped in a connect function needs to also be wrapped in a withRouter function."
I've just bumped into this and for now this solved my routing issue which I think was the exact same as yours, here is my repo https://github.com/iuliaL/diagonistician-ReactJS-Express-Mongoose-RestAPI, checkout jwt branch :)
When on /list, can't go to /question/:id or to /list/add if I don't wrap Application component with withRouter; the path changes accordingly but no actual switch happens
I think it's something about the react-router version 4
Wrapping every connected component in withRouter is not optimal. See this guide for more information https://github.com/ReactTraining/react-router/blob/master/packages/react-router/docs/guides/blocked-updates.md
@pshrmn, Certainly not optimal, but based on the doc you linked it sounds like the right approach.
What happens when the component isn't being rendered by a
<Route>and the component rendering it does not have thelocationin its variable scope?
You can wrap a component with thewithRouterhigher-order component and it will be given the currentlocationas one of its props.
Of course I could be a little more specific and grep through each redux implementation I have, there's a lot, and pick out just the ones that really need it, but at the end of the day I don't want to think about that. And there's the issue of when I add another nested child and it doesn't update as expected because I didn't just wrap the parent with the withRouter HOC.
To that end I plan to add a HOC for the react-redux connect function that just always gets wrapped with withRouter.
import { connect } from 'react-redux'
import { withRouter } from 'react-router-dom'
const withRouterConnect = (...connectArgs) =>
(component) => withRouter(connect(...connectArgs)(component))
export default withRouterConnect
// Example usage: same as react-redux connect
// export default connect(mapStateToProps, mapDispatchToProps)(TodoApp)
When I rewrote that guide, I was intending to steer people away from using withRouter everywhere, but if it works for you and you aren't noticing performance implications, I can understand the convenience.
At the very least, do not do that with connected components that are already being rendered by a <Route>.
// doing this
const MyComponent = withRouterConnect(...)(WrappedComponent)
const App = () => (
// ...
<Route path='/some-place' component={MyComponent} />
// ...
)
// produces this
<Route path='/some-place'>
<Route>
<ConnectWrapper>
<WrappedComponent />
</ConnectWrapper>
</Route>
</Route>
@pshrmn what is a decent way to solve this problem?
How to have the router rerender components after url change?
Lots of coders are having this issue, navigation/history/push are simply broken.
@damianobarbati The guide linked above describes what to do to deal with blocked updates.
I must say that the solution presented in the guide, though clear, is very inadequate.
This makes react-router an uncooperative companion to any moderately sized site that uses redux or mobx, which is a huge number of sites.
One can not afford the extra wrapping suggested in the guide simply to inject unneeded props just to circumvent the blocking. On top of the ugliness, it completely ruins modularity: whenever a component somewhere up the hierarchy gets connected to the redux-store, all nested components, no matter how deep, get blocked and stop routing. This is even a larger problem when different teams are responsible for these components.
I do not see why react-router should suffer from this deficiency whereas other libraries do not. E.g., a connected react-redux component does not get blocked if an ancestor is modified to connect too. Why can't react-router adopt the same solution?
Most helpful comment
I must say that the solution presented in the guide, though clear, is very inadequate.
This makes react-router an uncooperative companion to any moderately sized site that uses
reduxormobx, which is a huge number of sites.One can not afford the extra wrapping suggested in the guide simply to inject unneeded props just to circumvent the blocking. On top of the ugliness, it completely ruins modularity: whenever a component somewhere up the hierarchy gets connected to the redux-store, all nested components, no matter how deep, get blocked and stop routing. This is even a larger problem when different teams are responsible for these components.
I do not see why
react-routershould suffer from this deficiency whereas other libraries do not. E.g., a connectedreact-reduxcomponent does not get blocked if an ancestor is modified to connect too. Why can't react-router adopt the same solution?