ConnectedRouter is re-rendering when Redux store updates
See original GitHub issueI recently migrated from the deprecated react-router-redux
package to connected-react-router
in order to successfully update react-redux
to v6
. The migration went well enough thanks to the detailed docs for this project.
However, now that I am on v6.0.0
of both connected-react-router
and react-redux
I am noticing some strange things occurring with the ConnectedRouter
component.
First issue
As others have already stated, the ConnectedRouter
seems to be rendering two times on initial page load.
Second issue
This is the larger one for me, and I’m still trying to figure out why it is happening. Basically, on any update to the state of my redux
store, the ConnectedRouter
component re-renders, causing unnecessary re-renders of any child components below it.
I set up an example repo that you can clone to get more details. I’ll give a brief description here:
Description
I’ve setup my redux
store according to the docs in this repository. Assuming this, here is a basic example using ConnectedRouter
:
// App.js
const App = () => (
<Provider store={store}>
<ConnectedRouter history={history}>
<div>
<Nav />
<Switch>
<Route exact path="/" component={Home} />
<Route path="/about" component={About} />
</Switch>
</div>
</ConnectedRouter>
</Provider>
)
The Home
component renders a child IncrementCount
component which dispatches an action to increment the count value stored in redux
store:
// IncrementCount.js
import { increment } from './actions'
const IncrementCount = ({ increment }) => (
<button onClick={increment}>Increment</button>
)
export default connect(null, { increment })(IncrementCount)
The About
component renders a child CountValue
component which displays the current count:
// CountValue.js
const CountValue = ({ value }) => (
<div>{value}</div>
)
const mapStateToProps = ({ app }) => ({
value: app.count
})
export default connect(mapStateToProps)(CountValue)
When incrementing the count on the '/'
route, the ConnectedRouter
re-renders along with the Nav
component (doesn’t even connect to the redux store), and the Home
component.
This is not the expected behavior.
The expected behavior occurs when replacing ConnectedRouter
with BrowserRouter
from the react-router-dom
library:
// with BrowserRouter
const App = () => (
<Provider store={store}>
<BrowserRouter>
<div>
<Nav />
<Switch>
<Route exact path="/" component={Home} />
<Route path="/about" component={About} />
</Switch>
</div>
</ConnectedRouter>
</Provider>
)
In the code above, incrementing the count value on the '/'
route does not cause any unnecessary re-renders to the Nav
or Home
components.
Issue Analytics
- State:
- Created 5 years ago
- Reactions:25
- Comments:20 (3 by maintainers)
FWIW I’m getting an
Invariant Violation: Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.
error when calling setState incomponentDidMount
due to the multiple renders@radziksh This has no affect on either of the problems this issue is trying to examine.
What versions of
react-redux
andconnected-react-router
are you using? The comment you posted is coming from an issue that references a different version ofconnected-react-router
.