Skip to content

Commit 9a2b026

Browse files
taiontimdorr
authored andcommitted
Support history v3 (#3647)
1 parent e5bf389 commit 9a2b026

File tree

6 files changed

+53
-53
lines changed

6 files changed

+53
-53
lines changed

modules/Router.js

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,6 @@ import { createRoutes } from './RouteUtils'
88
import { createRouterObject, assignRouterState } from './RouterUtils'
99
import warning from './routerWarning'
1010

11-
/* istanbul ignore next: sanity check */
12-
function isUnsupportedHistory(history) {
13-
// v3 histories expose getCurrentLocation, but aren't currently supported.
14-
return history && history.getCurrentLocation
15-
}
16-
1711
const { func, object } = React.PropTypes
1812

1913
/**
@@ -82,10 +76,10 @@ const Router = React.createClass({
8276
const { routes, children } = this.props
8377

8478
invariant(
85-
!isUnsupportedHistory(history),
86-
'You have provided a history object created with history v3.x. ' +
87-
'This version of React Router is not compatible with v3 history ' +
88-
'objects. Please use history v2.x instead.'
79+
history.getCurrentLocation,
80+
'You have provided a history object created with history v2.x or ' +
81+
'earlier. This version of React Router is only compatible with v3 ' +
82+
'history objects. Please upgrade to history v3.x.'
8983
)
9084

9185
return createTransitionManager(

modules/__tests__/serverRendering-test.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -183,13 +183,13 @@ describe('server rendering', function () {
183183
})
184184
})
185185

186-
describe('server/client consistency', function () {
186+
describe('server/client consistency', () => {
187187
// Just render to static markup here to avoid having to normalize markup.
188188

189-
it('should match for synchronous route', function () {
189+
it('should match for synchronous route', () => {
190190
let serverString
191191

192-
match({ routes, location: '/dashboard' }, function (error, redirectLocation, renderProps) {
192+
match({ routes, location: '/dashboard' }, (error, redirectLocation, renderProps) => {
193193
serverString = renderToStaticMarkup(
194194
<RouterContext {...renderProps} />
195195
)
@@ -202,13 +202,13 @@ describe('server rendering', function () {
202202
expect(browserString).toEqual(serverString)
203203
})
204204

205-
it('should match for asynchronous route', function (done) {
206-
match({ routes, location: '/async' }, function (error, redirectLocation, renderProps) {
205+
it('should match for asynchronous route', done => {
206+
match({ routes, location: '/async' }, (error, redirectLocation, renderProps) => {
207207
const serverString = renderToStaticMarkup(
208208
<RouterContext {...renderProps} />
209209
)
210210

211-
match({ history: createMemoryHistory('/async'), routes }, function (error, redirectLocation, renderProps) {
211+
match({ history: createMemoryHistory('/async'), routes }, (error, redirectLocation, renderProps) => {
212212
const browserString = renderToStaticMarkup(
213213
<Router {...renderProps} />
214214
)

modules/__tests__/useRouterHistory-test.js

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ import Redirect from '../Redirect'
88
import Router from '../Router'
99
import Route from '../Route'
1010

11-
describe('useRouterHistory', function () {
12-
it('passes along options, especially query parsing', function (done) {
11+
describe('useRouterHistory', () => {
12+
it('passes along options, especially query parsing', done => {
1313
const history = useRouterHistory(createHistory)({
1414
stringifyQuery() {
1515
assert(true)
@@ -20,40 +20,46 @@ describe('useRouterHistory', function () {
2020
history.push({ pathname: '/', query: { test: true } })
2121
})
2222

23-
describe('when using basename', function () {
23+
describe('when using basename', () => {
2424

2525
let node
26-
beforeEach(function () {
26+
beforeEach(() => {
2727
node = document.createElement('div')
2828
})
2929

30-
afterEach(function () {
30+
afterEach(() => {
3131
unmountComponentAtNode(node)
3232
})
3333

34-
it('should regard basename', function (done) {
35-
const pathnames = []
36-
const basenames = []
34+
it('should regard basename', () => {
3735
const history = useRouterHistory(createHistory)({
3836
entries: '/foo/notes/5',
3937
basename: '/foo'
4038
})
41-
history.listen(function (location) {
39+
40+
const pathnames = []
41+
const basenames = []
42+
43+
const currentLocation = history.getCurrentLocation()
44+
pathnames.push(currentLocation.pathname)
45+
basenames.push(currentLocation.basename)
46+
47+
history.listen(location => {
4248
pathnames.push(location.pathname)
4349
basenames.push(location.basename)
4450
})
45-
render((
51+
52+
const instance = render((
4653
<Router history={history}>
4754
<Route path="/messages/:id" />
4855
<Redirect from="/notes/:id" to="/messages/:id" />
4956
</Router>
50-
), node, function () {
51-
expect(pathnames).toEqual([ '/notes/5', '/messages/5' ])
52-
expect(basenames).toEqual([ '/foo', '/foo' ])
53-
expect(this.state.location.pathname).toEqual('/messages/5')
54-
expect(this.state.location.basename).toEqual('/foo')
55-
done()
56-
})
57+
), node)
58+
59+
expect(pathnames).toEqual([ '/notes/5', '/messages/5' ])
60+
expect(basenames).toEqual([ '/foo', '/foo' ])
61+
expect(instance.state.location.pathname).toEqual('/messages/5')
62+
expect(instance.state.location.basename).toEqual('/foo')
5763
})
5864
})
5965
})

modules/createTransitionManager.js

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -216,9 +216,7 @@ export default function createTransitionManager(history, routes) {
216216
* gracefully handle errors and redirects.
217217
*/
218218
function listen(listener) {
219-
// TODO: Only use a single history listener. Otherwise we'll
220-
// end up with multiple concurrent calls to match.
221-
return history.listen(function (location) {
219+
function historyListener(location) {
222220
if (state.location === location) {
223221
listener(null, state)
224222
} else {
@@ -238,7 +236,22 @@ export default function createTransitionManager(history, routes) {
238236
}
239237
})
240238
}
241-
})
239+
}
240+
241+
// TODO: Only use a single history listener. Otherwise we'll end up with
242+
// multiple concurrent calls to match.
243+
244+
// Set up the history listener first in case the initial match redirects.
245+
const unsubscribe = history.listen(historyListener)
246+
247+
if (state.location) {
248+
// Picking up on a matchContext.
249+
listener(null, state)
250+
} else {
251+
historyListener(history.getCurrentLocation())
252+
}
253+
254+
return unsubscribe
242255
}
243256

244257
return {

modules/match.js

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -26,20 +26,14 @@ function match({ history, routes, location, ...options }, callback) {
2626
createRoutes(routes)
2727
)
2828

29-
let unlisten
30-
3129
if (location) {
3230
// Allow match({ location: '/the/path', ... })
3331
location = history.createLocation(location)
3432
} else {
35-
// Pick up the location from the history via synchronous history.listen
36-
// call if needed.
37-
unlisten = history.listen(historyLocation => {
38-
location = historyLocation
39-
})
33+
location = history.getCurrentLocation()
4034
}
4135

42-
transitionManager.match(location, function (error, redirectLocation, nextState) {
36+
transitionManager.match(location, (error, redirectLocation, nextState) => {
4337
let renderProps
4438

4539
if (nextState) {
@@ -52,13 +46,6 @@ function match({ history, routes, location, ...options }, callback) {
5246
}
5347

5448
callback(error, redirectLocation, renderProps)
55-
56-
// Defer removing the listener to here to prevent DOM histories from having
57-
// to unwind DOM event listeners unnecessarily, in case callback renders a
58-
// <Router> and attaches another history listener.
59-
if (unlisten) {
60-
unlisten()
61-
}
6249
})
6350
}
6451

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
],
3333
"license": "MIT",
3434
"dependencies": {
35-
"history": "^2.1.2",
35+
"history": "^3.0.0",
3636
"hoist-non-react-statics": "^1.2.0",
3737
"invariant": "^2.2.1",
3838
"warning": "^3.0.0",

0 commit comments

Comments
 (0)