diff --git a/docs/API.md b/docs/API.md index f5b0c169b6..d629daeafb 100644 --- a/docs/API.md +++ b/docs/API.md @@ -350,7 +350,7 @@ Called on routes when the location changes, but the route itself neither enters If `callback` is listed as a 4th argument, this hook will run asynchronously, and the transition will block until `callback` is called. -##### `onLeave()` +##### `onLeave(prevState)` Called when a route is about to be exited. diff --git a/docs/Glossary.md b/docs/Glossary.md index 366991e234..ee1d49052b 100644 --- a/docs/Glossary.md +++ b/docs/Glossary.md @@ -66,10 +66,10 @@ A *hash* is a string that represents the hash portion of the URL. It is synonymo ## LeaveHook ```js -type LeaveHook = () => any; +type LeaveHook = (prevState: RouterState) => any; ``` -A *leave hook* is a user-defined function that is called when a route is about to be unmounted. +A *leave hook* is a user-defined function that is called when a route is about to be unmounted. It receives the previous [router state](#routerstate) as its first argument. ## Location diff --git a/modules/TransitionUtils.js b/modules/TransitionUtils.js index 078c8aab6d..444574432e 100644 --- a/modules/TransitionUtils.js +++ b/modules/TransitionUtils.js @@ -104,8 +104,8 @@ export function runChangeHooks(routes, state, nextState, callback) { /** * Runs all onLeave hooks in the given array of routes in order. */ -export function runLeaveHooks(routes) { +export function runLeaveHooks(routes, prevState) { for (let i = 0, len = routes.length; i < len; ++i) if (routes[i].onLeave) - routes[i].onLeave.call(routes[i]) + routes[i].onLeave.call(routes[i], prevState) } diff --git a/modules/__tests__/transitionHooks-test.js b/modules/__tests__/transitionHooks-test.js index 3e6b6c392b..586428a5f1 100644 --- a/modules/__tests__/transitionHooks-test.js +++ b/modules/__tests__/transitionHooks-test.js @@ -90,8 +90,9 @@ describe('When a router enters a branch', function () { expect(nextState.routes).toContain(NewsFeedRoute) expect(replace).toBeA('function') }, - onLeave() { + onLeave(prevState) { expect(this).toBe(NewsFeedRoute) + expect(prevState.routes).toContain(NewsFeedRoute) } } @@ -103,8 +104,9 @@ describe('When a router enters a branch', function () { expect(nextState.routes).toContain(InboxRoute) expect(replace).toBeA('function') }, - onLeave() { + onLeave(prevState) { expect(this).toBe(InboxRoute) + expect(prevState.routes).toContain(InboxRoute) } } @@ -117,8 +119,9 @@ describe('When a router enters a branch', function () { replace('/inbox') }, - onLeave() { + onLeave(prevState) { expect(this).toBe(RedirectToInboxRoute) + expect(prevState.routes).toContain(RedirectToInboxRoute) } } @@ -135,8 +138,9 @@ describe('When a router enters a branch', function () { expect(nextState.routes).toContain(MessageRoute) expect(replace).toBeA('function') }, - onLeave() { + onLeave(prevState) { expect(this).toBe(MessageRoute) + expect(prevState.routes).toContain(MessageRoute) } } @@ -170,8 +174,9 @@ describe('When a router enters a branch', function () { expect(nextState.routes).toContain(DashboardRoute) expect(replace).toBeA('function') }, - onLeave() { + onLeave(prevState) { expect(this).toBe(DashboardRoute) + expect(prevState.routes).toContain(DashboardRoute) }, childRoutes: [ NewsFeedRoute, InboxRoute, RedirectToInboxRoute, MessageRoute, UserRoute ] } diff --git a/modules/createTransitionManager.js b/modules/createTransitionManager.js index 6aca387361..d21f21409d 100644 --- a/modules/createTransitionManager.js +++ b/modules/createTransitionManager.js @@ -69,7 +69,7 @@ export default function createTransitionManager(history, routes) { function finishMatch(nextState, callback) { const { leaveRoutes, changeRoutes, enterRoutes } = computeChangedRoutes(state, nextState) - runLeaveHooks(leaveRoutes) + runLeaveHooks(leaveRoutes, state) // Tear down confirmation hooks for left routes leaveRoutes