Skip to content

Commit b8f1abe

Browse files
committed
[changed] Removed (un)registerRouteHook
Use listenBeforeLeavingRoute instead.
1 parent 08ada07 commit b8f1abe

File tree

2 files changed

+68
-51
lines changed

2 files changed

+68
-51
lines changed

modules/Lifecycle.js

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,18 @@ import invariant from 'invariant'
33

44
const { object } = React.PropTypes
55

6+
function getRoute(element) {
7+
const route = element.props.route || element.context.route
8+
9+
invariant(
10+
route,
11+
'The Lifecycle mixin needs to be used either on 1) a <Route component> or ' +
12+
'2) a descendant of a <Route component> that uses the RouteContext mixin'
13+
)
14+
15+
return route
16+
}
17+
618
/**
719
* The Lifecycle mixin adds the routerWillLeave lifecycle method
820
* to a component that may be used to cancel a transition or prompt
@@ -33,35 +45,21 @@ const Lifecycle = {
3345
route: object
3446
},
3547

36-
_getRoute() {
37-
const route = this.props.route || this.context.route
38-
39-
invariant(
40-
route,
41-
'The Lifecycle mixin needs to be used either on 1) a <Route component> or ' +
42-
'2) a descendant of a <Route component> that uses the RouteContext mixin'
43-
)
44-
45-
return route
46-
},
47-
4848
componentWillMount() {
4949
invariant(
5050
this.routerWillLeave,
5151
'The Lifecycle mixin requires you to define a routerWillLeave method'
5252
)
5353

54-
this.context.history.registerRouteHook(
55-
this._getRoute(),
54+
this._unlistenBeforeLeavingRoute = this.context.history.listenBeforeLeavingRoute(
55+
getRoute(this),
5656
this.routerWillLeave
5757
)
5858
},
5959

6060
componentWillUnmount() {
61-
this.context.history.unregisterRouteHook(
62-
this._getRoute(),
63-
this.routerWillLeave
64-
)
61+
if (this._unlistenBeforeLeavingRoute)
62+
this._unlistenBeforeLeavingRoute()
6563
}
6664

6765
}

modules/useRoutes.js

Lines changed: 52 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,8 @@ function hasAnyProperties(object) {
2121
* history objects that know about routing.
2222
*
2323
* - isActive(pathname, query)
24-
* - registerRouteHook(route, (location) => {})
25-
* - unregisterRouteHook(route, (location) => {})
2624
* - match(location, (error, nextState, nextLocation) => {})
25+
* - listenBeforeLeavingRoute(route, (?nextLocation) => {})
2726
* - listen((error, nextState) => {})
2827
*/
2928
function useRoutes(createHistory) {
@@ -88,14 +87,14 @@ function useRoutes(createHistory) {
8887
})
8988
}
9089

91-
const RouteHooks = {}
92-
9390
let RouteGuid = 1
9491

9592
function getRouteID(route) {
9693
return route.__id__ || (route.__id__ = RouteGuid++)
9794
}
9895

96+
const RouteHooks = {}
97+
9998
function getRouteHooksForRoutes(routes) {
10099
return routes.reduce(function (hooks, route) {
101100
hooks.push.apply(hooks, RouteHooks[getRouteID(route)])
@@ -133,8 +132,8 @@ function useRoutes(createHistory) {
133132
}
134133

135134
function beforeUnloadHook() {
136-
// Synchronously check to see if any route hooks want to
137-
// prevent the current window/tab from closing.
135+
// Synchronously check to see if any route hooks want
136+
// to prevent the current window/tab from closing.
138137
if (state.routes) {
139138
let hooks = getRouteHooksForRoutes(state.routes)
140139

@@ -149,7 +148,22 @@ function useRoutes(createHistory) {
149148
}
150149
}
151150

152-
function registerRouteHook(route, hook) {
151+
let unlistenBefore, unlistenBeforeUnload
152+
153+
/**
154+
* Registers the given hook function to run before leaving the given route.
155+
*
156+
* During a normal transition, the hook function receives the next location
157+
* as its only argument and must return either a) a prompt message to show
158+
* the user, to make sure they want to leave the page or b) false, to prevent
159+
* the transition.
160+
*
161+
* During the beforeunload event (in browsers) the hook receives no arguments.
162+
* In this case it must return a prompt message to prevent the transition.
163+
*
164+
* Returns a function that may be used to unbind the listener.
165+
*/
166+
function listenBeforeLeavingRoute(route, hook) {
153167
// TODO: Warn if they register for a route that isn't currently
154168
// active. They're probably doing something wrong, like re-creating
155169
// route objects on every location change.
@@ -162,34 +176,40 @@ function useRoutes(createHistory) {
162176
hooks = RouteHooks[routeID] = [ hook ]
163177

164178
if (thereWereNoRouteHooks) {
165-
history.registerTransitionHook(transitionHook)
179+
// setup transition & beforeunload hooks
180+
unlistenBefore = history.listenBefore(transitionHook)
166181

167-
if (history.registerBeforeUnloadHook)
168-
history.registerBeforeUnloadHook(beforeUnloadHook)
182+
if (history.listenBeforeUnload)
183+
unlistenBeforeUnload = history.listenBeforeUnload(beforeUnloadHook)
169184
}
170185
} else if (hooks.indexOf(hook) === -1) {
171186
hooks.push(hook)
172187
}
173-
}
174-
175-
function unregisterRouteHook(route, hook) {
176-
let routeID = getRouteID(route)
177-
let hooks = RouteHooks[routeID]
178-
179-
if (hooks != null) {
180-
let newHooks = hooks.filter(item => item !== hook)
181-
182-
if (newHooks.length === 0) {
183-
delete RouteHooks[routeID]
184-
185-
if (!hasAnyProperties(RouteHooks)) {
186-
history.unregisterTransitionHook(transitionHook)
187-
188-
if (history.unregisterBeforeUnloadHook)
189-
history.unregisterBeforeUnloadHook(beforeUnloadHook)
188+
189+
return function () {
190+
let hooks = RouteHooks[routeID]
191+
192+
if (hooks != null) {
193+
let newHooks = hooks.filter(item => item !== hook)
194+
195+
if (newHooks.length === 0) {
196+
delete RouteHooks[routeID]
197+
198+
if (!hasAnyProperties(RouteHooks)) {
199+
// teardown transition & beforeunload hooks
200+
if (unlistenBefore) {
201+
unlistenBefore()
202+
unlistenBefore = null
203+
}
204+
205+
if (unlistenBeforeUnload) {
206+
unlistenBeforeUnload()
207+
unlistenBeforeUnload = null
208+
}
209+
}
210+
} else {
211+
RouteHooks[routeID] = newHooks
190212
}
191-
} else {
192-
RouteHooks[routeID] = newHooks
193213
}
194214
}
195215
}
@@ -229,10 +249,9 @@ function useRoutes(createHistory) {
229249
return {
230250
...history,
231251
isActive,
232-
registerRouteHook,
233-
unregisterRouteHook,
234-
listen,
235-
match
252+
match,
253+
listenBeforeLeavingRoute,
254+
listen
236255
}
237256
}
238257
}

0 commit comments

Comments
 (0)