Skip to content

Commit f64659d

Browse files
committed
Merge pull request #3443 from gaearon/with-router-static
Make withRouter() update inside static containers
2 parents 72ed6e7 + 893cbf0 commit f64659d

File tree

5 files changed

+39
-2
lines changed

5 files changed

+39
-2
lines changed

modules/ContextUtils.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { PropTypes } from 'react'
22

33
// Works around issues with context updates failing to propagate.
4+
// Caveat: the context value is expected to never change its identity.
45
// https://github.com/facebook/react/issues/2517
56
// https://github.com/reactjs/react-router/issues/470
67

modules/Router.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import RouterContext from './RouterContext'
66
import { createRoutes } from './RouteUtils'
77
import { createRouterObject } from './RouterUtils'
88
import warning from './routerWarning'
9+
import assign from 'object-assign'
910

1011
const { func, object } = React.PropTypes
1112

@@ -88,7 +89,9 @@ const Router = React.createClass({
8889
if (error) {
8990
this.handleError(error)
9091
} else {
91-
this.router = this.createRouterObject(state)
92+
// Keep the identity of this.router because of a caveat in ContextUtils:
93+
// they only work if the object identity is preserved.
94+
assign(this.router, this.createRouterObject(state))
9295
this.setState(state, this.props.onUpdate)
9396
}
9497
})

modules/__tests__/withRouter-test.js

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ describe('withRouter', function () {
1111
class App extends Component {
1212
render() {
1313
expect(this.props.router).toExist()
14-
return <h1>App</h1>
14+
return <h1>{this.props.router.location.pathname}</h1>
1515
}
1616
}
1717

@@ -39,4 +39,34 @@ describe('withRouter', function () {
3939
done()
4040
})
4141
})
42+
43+
it('updates the context inside static containers', function (done) {
44+
const WrappedApp = withRouter(App)
45+
46+
class StaticContainer extends Component {
47+
shouldComponentUpdate() {
48+
return false
49+
}
50+
51+
render() {
52+
return this.props.children
53+
}
54+
}
55+
56+
const history = createHistory('/')
57+
58+
render((
59+
<Router history={history}>
60+
<Route component={StaticContainer}>
61+
<Route path="/" component={WrappedApp} />
62+
<Route path="/hello" component={WrappedApp} />
63+
</Route>
64+
</Router>
65+
), node, function () {
66+
expect(node.firstChild.textContent).toEqual('/')
67+
history.push('/hello')
68+
expect(node.firstChild.textContent).toEqual('/hello')
69+
done()
70+
})
71+
})
4272
})

modules/withRouter.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import React from 'react'
22
import hoistStatics from 'hoist-non-react-statics'
3+
import { ContextSubscriber } from './ContextUtils'
34
import { routerShape } from './PropTypes'
45

56
function getDisplayName(WrappedComponent) {
@@ -8,6 +9,7 @@ function getDisplayName(WrappedComponent) {
89

910
export default function withRouter(WrappedComponent) {
1011
const WithRouter = React.createClass({
12+
mixins: [ ContextSubscriber('router') ],
1113
contextTypes: { router: routerShape },
1214
render() {
1315
return <WrappedComponent {...this.props} router={this.context.router} />

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
"history": "^2.0.1",
3636
"hoist-non-react-statics": "^1.0.5",
3737
"invariant": "^2.2.1",
38+
"object-assign": "^4.1.0",
3839
"warning": "^2.1.0"
3940
},
4041
"peerDependencies": {

0 commit comments

Comments
 (0)