Skip to content

Commit 39b36f2

Browse files
committed
Merge pull request #3107 from taion/leave-hook-teardown
Don't tear down leave hooks when not leaving
2 parents f9fc1f9 + 7fa5dde commit 39b36f2

File tree

2 files changed

+55
-16
lines changed

2 files changed

+55
-16
lines changed

modules/__tests__/transitionHooks-test.js

Lines changed: 52 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,15 @@ import Router from '../Router'
88

99
describe('When a router enters a branch', function () {
1010
let
11-
node, leaveHookSpy, removeLeaveHook,
12-
DashboardRoute, NewsFeedRoute, InboxRoute, RedirectToInboxRoute, MessageRoute,
11+
node,
12+
newsLeaveHookSpy, removeNewsLeaveHook, userLeaveHookSpy,
13+
DashboardRoute, NewsFeedRoute, InboxRoute, RedirectToInboxRoute, MessageRoute, UserRoute,
1314
routes
1415

1516
beforeEach(function () {
1617
node = document.createElement('div')
17-
leaveHookSpy = expect.createSpy()
18+
newsLeaveHookSpy = expect.createSpy()
19+
userLeaveHookSpy = expect.createSpy()
1820

1921
class Dashboard extends Component {
2022
render() {
@@ -29,9 +31,9 @@ describe('When a router enters a branch', function () {
2931

3032
class NewsFeed extends Component {
3133
componentWillMount() {
32-
removeLeaveHook = this.context.router.setRouteLeaveHook(
34+
removeNewsLeaveHook = this.context.router.setRouteLeaveHook(
3335
this.props.route,
34-
() => leaveHookSpy() // Break reference equality.
36+
() => newsLeaveHookSpy() // Break reference equality.
3537
)
3638
}
3739

@@ -50,6 +52,23 @@ describe('When a router enters a branch', function () {
5052
}
5153
}
5254

55+
class User extends Component {
56+
componentWillMount() {
57+
this.context.router.setRouteLeaveHook(
58+
this.props.route,
59+
userLeaveHookSpy
60+
)
61+
}
62+
63+
render() {
64+
return <div>User</div>
65+
}
66+
}
67+
68+
User.contextTypes = {
69+
router: React.PropTypes.object.isRequired
70+
}
71+
5372
NewsFeedRoute = {
5473
path: 'news',
5574
component: NewsFeed,
@@ -102,6 +121,11 @@ describe('When a router enters a branch', function () {
102121
}
103122
}
104123

124+
UserRoute = {
125+
path: 'users/:userId',
126+
component: User
127+
}
128+
105129
DashboardRoute = {
106130
path: '/',
107131
component: Dashboard,
@@ -113,7 +137,7 @@ describe('When a router enters a branch', function () {
113137
onLeave() {
114138
expect(this).toBe(DashboardRoute)
115139
},
116-
childRoutes: [ NewsFeedRoute, InboxRoute, RedirectToInboxRoute, MessageRoute ]
140+
childRoutes: [ NewsFeedRoute, InboxRoute, RedirectToInboxRoute, MessageRoute, UserRoute ]
117141
}
118142

119143
routes = [
@@ -139,17 +163,14 @@ describe('When a router enters a branch', function () {
139163
it('calls the route leave hooks when leaving the route', function (done) {
140164
const history = createHistory('/news')
141165

142-
// Stub this function to exercise the code path.
143-
history.listenBeforeUnload = () => (() => {})
144-
145166
render(<Router history={history} routes={routes}/>, node, function () {
146-
expect(leaveHookSpy.calls.length).toEqual(0)
167+
expect(newsLeaveHookSpy.calls.length).toEqual(0)
147168
history.push('/inbox')
148-
expect(leaveHookSpy.calls.length).toEqual(1)
169+
expect(newsLeaveHookSpy.calls.length).toEqual(1)
149170
history.push('/news')
150-
expect(leaveHookSpy.calls.length).toEqual(1)
171+
expect(newsLeaveHookSpy.calls.length).toEqual(1)
151172
history.push('/inbox')
152-
expect(leaveHookSpy.calls.length).toEqual(2)
173+
expect(newsLeaveHookSpy.calls.length).toEqual(2)
153174
done()
154175
})
155176
})
@@ -158,9 +179,25 @@ describe('When a router enters a branch', function () {
158179
const history = createHistory('/news')
159180

160181
render(<Router history={history} routes={routes}/>, node, function () {
161-
removeLeaveHook()
182+
removeNewsLeaveHook()
162183
history.push('/inbox')
163-
expect(leaveHookSpy).toNotHaveBeenCalled()
184+
expect(newsLeaveHookSpy).toNotHaveBeenCalled()
185+
done()
186+
})
187+
})
188+
189+
it('does not remove route leave hooks when changing params', function (done) {
190+
const history = createHistory('/users/foo')
191+
192+
// Stub this function to exercise the code path.
193+
history.listenBeforeUnload = () => (() => {})
194+
195+
render(<Router history={history} routes={routes}/>, node, function () {
196+
expect(userLeaveHookSpy.calls.length).toEqual(0)
197+
history.push('/users/bar')
198+
expect(userLeaveHookSpy.calls.length).toEqual(1)
199+
history.push('/users/baz')
200+
expect(userLeaveHookSpy.calls.length).toEqual(2)
164201
done()
165202
})
166203
})

modules/createTransitionManager.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,9 @@ export default function createTransitionManager(history, routes) {
7272
runLeaveHooks(leaveRoutes)
7373

7474
// Tear down confirmation hooks for left routes
75-
leaveRoutes.forEach(removeListenBeforeHooksForRoute)
75+
leaveRoutes
76+
.filter(route => enterRoutes.indexOf(route) === -1)
77+
.forEach(removeListenBeforeHooksForRoute)
7678

7779
runEnterHooks(enterRoutes, nextState, function (error, redirectInfo) {
7880
if (error) {

0 commit comments

Comments
 (0)