From 96ed93697deb9f73f8b2c9e87f6f26c70b33b30a Mon Sep 17 00:00:00 2001 From: Ryan Florence Date: Wed, 9 Mar 2016 15:44:34 -0800 Subject: [PATCH 1/2] add failing test When moving from the first path to the second: /parent/123/child/456 /parent/789/child/456 The route hooks on parent are appropriately called, but not on the child. --- modules/__tests__/transitionHooks-test.js | 54 +++++++++++++++++++++-- 1 file changed, 51 insertions(+), 3 deletions(-) diff --git a/modules/__tests__/transitionHooks-test.js b/modules/__tests__/transitionHooks-test.js index 625c11600b..7a6bf792df 100644 --- a/modules/__tests__/transitionHooks-test.js +++ b/modules/__tests__/transitionHooks-test.js @@ -10,7 +10,7 @@ describe('When a router enters a branch', function () { let node, newsLeaveHookSpy, removeNewsLeaveHook, userLeaveHookSpy, - DashboardRoute, NewsFeedRoute, InboxRoute, RedirectToInboxRoute, MessageRoute, UserRoute, + DashboardRoute, NewsFeedRoute, InboxRoute, RedirectToInboxRoute, MessageRoute, UserRoute, AssignmentRoute, routes beforeEach(function () { @@ -52,6 +52,12 @@ describe('When a router enters a branch', function () { } } + class UserAssignment extends Component { + render() { + return
assignment {this.props.params.assignmentId}
+ } + } + class User extends Component { componentWillMount() { this.context.router.setRouteLeaveHook( @@ -61,7 +67,7 @@ describe('When a router enters a branch', function () { } render() { - return
User
+ return
User {this.props.params.userId} {this.props.children}
} } @@ -121,9 +127,19 @@ describe('When a router enters a branch', function () { } } + AssignmentRoute = { + path: 'assignments/:assignmentId', + component: UserAssignment, + onEnter() { expect(this).toBe(AssignmentRoute) }, + onLeave() { expect(this).toBe(AssignmentRoute) } + } + UserRoute = { path: 'users/:userId', - component: User + component: User, + childRoutes: [ AssignmentRoute ], + onEnter() { expect(this).toBe(UserRoute) }, + onLeave() { expect(this).toBe(UserRoute) } } DashboardRoute = { @@ -277,6 +293,38 @@ describe('When a router enters a branch', function () { }) }) + describe('and then navigates to the same branch, but with different parent params', function () { + it('calls the onLeave and onEnter hooks of the parent and children', function (done) { + const parentLeaveSpy = spyOn(UserRoute, 'onLeave').andCallThrough() + const parentEnterSpy = spyOn(UserRoute, 'onEnter').andCallThrough() + const childLeaveSpy = spyOn(AssignmentRoute, 'onLeave').andCallThrough() + const childEnterSpy = spyOn(AssignmentRoute, 'onEnter').andCallThrough() + const history = createHistory('/users/123/assignments/456') + + const steps = [ + function () { + expect(parentEnterSpy).toHaveBeenCalled() + expect(childEnterSpy).toHaveBeenCalled() + history.push('/users/789/assignments/456') + }, + function () { + expect(parentLeaveSpy).toHaveBeenCalled() + expect(childLeaveSpy).toHaveBeenCalled() + expect(parentEnterSpy).toHaveBeenCalled() + expect(childEnterSpy).toHaveBeenCalled() + } + ] + + const execNextStep = execSteps(steps, done) + + render( + , node, execNextStep) + }) + }) + describe('and then the query changes', function () { it('calls the onEnter hooks of all routes in that branch', function (done) { const newsFeedRouteEnterSpy = spyOn(NewsFeedRoute, 'onEnter').andCallThrough() From d5747e987cf724eb9aa75d19fa3d173574c91db6 Mon Sep 17 00:00:00 2001 From: Ryan Florence Date: Wed, 9 Mar 2016 15:46:33 -0800 Subject: [PATCH 2/2] fixed incorrect leave behavior test is in parent commit --- CHANGES.md | 5 ++++- modules/computeChangedRoutes.js | 10 +++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index ff5a472b85..f8e7818841 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,7 +1,10 @@ ## [HEAD] > Unreleased -- Nothing yet! +- Fixed bug where transition hooks were not called on child routes of + parent's whose params changed but the child's did not. ([#3166]) + +[#3166][https://github.com/reactjs/react-router/pull/3166] [HEAD]: https://github.com/reactjs/react-router/compare/v2.0.0...HEAD diff --git a/modules/computeChangedRoutes.js b/modules/computeChangedRoutes.js index 05c386dacc..e8a6b9e152 100644 --- a/modules/computeChangedRoutes.js +++ b/modules/computeChangedRoutes.js @@ -27,8 +27,16 @@ function computeChangedRoutes(prevState, nextState) { let leaveRoutes, enterRoutes if (prevRoutes) { + let parentIsLeaving = false leaveRoutes = prevRoutes.filter(function (route) { - return nextRoutes.indexOf(route) === -1 || routeParamsChanged(route, prevState, nextState) + if (parentIsLeaving) { + return true + } else { + const isLeaving = nextRoutes.indexOf(route) === -1 || routeParamsChanged(route, prevState, nextState) + if (isLeaving) + parentIsLeaving = true + return isLeaving + } }) // onLeave hooks start at the leaf route.