diff --git a/modules/__tests__/transitionHooks-test.js b/modules/__tests__/transitionHooks-test.js index 6e998ab188..57d2e86fe2 100644 --- a/modules/__tests__/transitionHooks-test.js +++ b/modules/__tests__/transitionHooks-test.js @@ -3,6 +3,7 @@ import expect, { spyOn } from 'expect' import React from 'react' import createHistory from 'history/lib/createMemoryHistory' +import useQueries from 'history/lib/useQueries' import execSteps from './execSteps' import Router from '../Router' @@ -193,4 +194,19 @@ describe('When a router enters a branch', function () { }) }) + 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() + const history = useQueries(createHistory)('/inbox') + + React.render(, node, function () { + history.pushState(null, '/news', { q: 1 }) + expect(newsFeedRouteEnterSpy.calls.length).toEqual(1) + history.pushState(null, '/news', { q: 2 }) + expect(newsFeedRouteEnterSpy.calls.length).toEqual(2) + done() + }) + }) + }) + }) diff --git a/modules/computeChangedRoutes.js b/modules/computeChangedRoutes.js index 05c386dacc..9487f07d24 100644 --- a/modules/computeChangedRoutes.js +++ b/modules/computeChangedRoutes.js @@ -11,11 +11,17 @@ function routeParamsChanged(route, prevState, nextState) { }) } +function routeQueryChanged(prevState, nextState) { + return prevState.location.search !== nextState.location.search +} + /** * Returns an object of { leaveRoutes, enterRoutes } determined by * the change from prevState to nextState. We leave routes if either * 1) they are not in the next state or 2) they are in the next state - * but their params have changed (i.e. /users/123 => /users/456). + * but their params have changed (i.e. /users/123 => /users/456) or + * 3) they are in the next state but the query has changed + * (i.e. /search?query=foo => /search?query=bar) * * leaveRoutes are ordered starting at the leaf route of the tree * we're leaving up to the common parent route. enterRoutes are ordered @@ -28,7 +34,9 @@ function computeChangedRoutes(prevState, nextState) { let leaveRoutes, enterRoutes if (prevRoutes) { leaveRoutes = prevRoutes.filter(function (route) { - return nextRoutes.indexOf(route) === -1 || routeParamsChanged(route, prevState, nextState) + return nextRoutes.indexOf(route) === -1 + || routeParamsChanged(route, prevState, nextState) + || routeQueryChanged(prevState, nextState) }) // onLeave hooks start at the leaf route.