Skip to content

Commit 5550cc3

Browse files
committed
Keep location in router state
Also, clean up unnecessary work in getChildContext
1 parent c8510da commit 5550cc3

File tree

2 files changed

+59
-31
lines changed

2 files changed

+59
-31
lines changed

modules/LocationUtils.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import { parsePath, createPath } from 'history/PathUtils'
22

3+
export { locationsAreEqual } from 'history/LocationUtils'
4+
35
const createRouterLocation = (input, parseQueryString, stringifyQuery) => {
46
if (typeof input === 'string') {
57
const location = parsePath(input)

modules/StaticRouter.js

Lines changed: 57 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
import React, { PropTypes } from 'react'
22
import { stringify, parse as parseQueryString } from 'query-string'
3-
import { createRouterLocation, createRouterPath } from './LocationUtils'
43
import MatchProvider from './MatchProvider'
4+
import {
5+
locationsAreEqual,
6+
createRouterLocation,
7+
createRouterPath
8+
} from './LocationUtils'
59
import {
610
action as actionType,
711
location as locationType,
@@ -31,61 +35,83 @@ class StaticRouter extends React.Component {
3135
}
3236

3337
static defaultProps = {
34-
createHref: path => path,
3538
stringifyQuery,
36-
parseQueryString
39+
parseQueryString,
40+
createHref: path => path
3741
}
3842

3943
static childContextTypes = {
4044
router: routerContextType.isRequired,
4145
location: locationType.isRequired // TODO: Remove location state from context
4246
}
4347

44-
createLocationForContext(loc) {
48+
createLocation(location) {
4549
const { parseQueryString, stringifyQuery } = this.props
46-
return createRouterLocation(loc, parseQueryString, stringifyQuery)
50+
return createRouterLocation(location, parseQueryString, stringifyQuery)
4751
}
4852

49-
getChildContext() {
50-
const createHref = (to) => {
51-
let path = createRouterPath(to, this.props.stringifyQuery)
52-
if (this.props.basename) path = this.props.basename + path
53-
return this.props.createHref(path)
54-
}
53+
transitionTo = (location) => {
54+
this.props.onPush(this.createLocation(location))
55+
}
56+
57+
replaceWith = (location) => {
58+
this.props.onReplace(this.createLocation(location))
59+
}
60+
61+
blockTransitions = (prompt) => {
62+
this.props.blockTransitions(prompt)
63+
}
5564

56-
const location = this.getLocation()
65+
createHref = (to) => {
66+
let path = createRouterPath(to, this.props.stringifyQuery)
67+
68+
if (this.props.basename)
69+
path = this.props.basename + path
70+
71+
return this.props.createHref(path)
72+
}
5773

74+
getRouterContext() {
5875
return {
59-
location,
60-
router: {
61-
createHref,
62-
transitionTo: (loc) => {
63-
this.props.onPush(this.createLocationForContext(loc))
64-
},
65-
replaceWith: (loc) => {
66-
this.props.onReplace(this.createLocationForContext(loc))
67-
},
68-
blockTransitions: (getPromptMessage) => {
69-
this.props.blockTransitions(getPromptMessage)
70-
}
71-
}
76+
transitionTo: this.transitionTo,
77+
replaceWith: this.replaceWith,
78+
blockTransitions: this.blockTransitions,
79+
createHref: this.createHref
7280
}
7381
}
7482

75-
getLocation() {
76-
// TODO: maybe memoize this on willReceiveProps to get extreme w/ perf
77-
const { location, parseQueryString, stringifyQuery } = this.props
78-
return createRouterLocation(location, parseQueryString, stringifyQuery)
83+
getChildContext() {
84+
return {
85+
location: this.state.location, // TODO: Remove location state from context
86+
router: this.getRouterContext()
87+
}
88+
}
89+
90+
state = {
91+
location: null
92+
}
93+
94+
componentWillMount() {
95+
this.setState({
96+
location: this.createLocation(this.props.location)
97+
})
98+
}
99+
100+
componentWillReceiveProps(nextProps) {
101+
const nextLocation = this.createLocation(nextProps.location)
102+
103+
if (!locationsAreEqual(this.state.location, nextLocation))
104+
this.setState({ location: nextLocation })
79105
}
80106

81107
render() {
108+
const { location } = this.state
82109
const { children } = this.props
83-
const location = this.getLocation()
84110

85111
return (
86112
<MatchProvider>
87113
{typeof children === 'function' ? (
88-
children({ location, router: this.getChildContext().router })
114+
children({ location, router: this.getRouterContext() })
89115
) : (
90116
React.Children.only(children)
91117
)}

0 commit comments

Comments
 (0)