diff --git a/package.json b/package.json index a24c37cb..613e53cd 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ "react-helmet": "^5.0.2", "react-intl": "^2.2.3", "react-redux": "^5.0.3", - "react-router-dom": "4.0.0-beta.6", + "react-router-dom": "^4.0.0", "react-sortable-hoc": "^0.6.1", "redux": "^3.6.0", "redux-form": "^6.6.1", diff --git a/src/Routes.js b/src/Routes.js index d7b0e0bd..6eced264 100644 --- a/src/Routes.js +++ b/src/Routes.js @@ -118,8 +118,14 @@ Routes.defaultProps = { staticContext: {} }; Routes.propTypes = { isAuthenticated: bool.isRequired, + + // from withFlattenedRoutes flattenedRoutes: arrayOf(propTypes.route).isRequired, + + // from withRouter staticContext: object, + + // from connect dispatch: func.isRequired, }; diff --git a/src/components/NamedLink/NamedLink.js b/src/components/NamedLink/NamedLink.js index 329699ab..171de1ab 100644 --- a/src/components/NamedLink/NamedLink.js +++ b/src/components/NamedLink/NamedLink.js @@ -63,16 +63,15 @@ NamedLinkComponent.propTypes = { // Link component props to: shape({ search: string, hash: string, state: object }), children: any, - // Note: The Link `replace` prop conflicts with the replace function - // from withRouter. If the replace boolean is required for the Link - // component, add it here with another name. // generic props for the underlying element className: string, style: object, activeClassName: string, + // from withFlattenedRoutes flattenedRoutes: arrayOf(propTypes.route).isRequired, + // from withRouter match: object, }; diff --git a/src/components/PageLayout/PageLayout.js b/src/components/PageLayout/PageLayout.js index 378383dc..d80563eb 100644 --- a/src/components/PageLayout/PageLayout.js +++ b/src/components/PageLayout/PageLayout.js @@ -15,7 +15,7 @@ const scrollToTop = () => { class PageLayout extends Component { componentDidMount() { - this.historyUnlisten = this.props.listen(() => scrollToTop()); + this.historyUnlisten = this.props.history.listen(() => scrollToTop()); } componentWillUnmount() { @@ -62,7 +62,7 @@ class PageLayout extends Component { } } -const { any, string, instanceOf, func } = PropTypes; +const { any, string, instanceOf, func, shape } = PropTypes; PageLayout.defaultProps = { className: '', children: null, authInfoError: null, logoutError: null }; @@ -72,8 +72,11 @@ PageLayout.propTypes = { children: any, authInfoError: instanceOf(Error), logoutError: instanceOf(Error), - // history.listen function from withRouter - listen: func.isRequired, + + // from withRouter + history: shape({ + listen: func.isRequired, + }).isRequired, }; const mapStateToProps = state => ({ diff --git a/src/containers/LandingPage/LandingPage.js b/src/containers/LandingPage/LandingPage.js index 39a7d1e0..40b2b096 100644 --- a/src/containers/LandingPage/LandingPage.js +++ b/src/containers/LandingPage/LandingPage.js @@ -8,13 +8,13 @@ import * as propTypes from '../../util/propTypes'; import css from './LandingPage.css'; export const LandingPageComponent = props => { - const { push: historyPush, flattenedRoutes } = props; + const { history, flattenedRoutes } = props; const handleSubmit = values => { const selectedPlace = values && values.location ? values.location.selectedPlace : null; const { address, origin, bounds } = selectedPlace || {}; const searchParams = { address, origin, bounds }; - historyPush(createResourceLocatorString('SearchPage', flattenedRoutes, {}, searchParams)); + history.push(createResourceLocatorString('SearchPage', flattenedRoutes, {}, searchParams)); }; return ( @@ -26,13 +26,15 @@ export const LandingPageComponent = props => { ); }; -const { func, arrayOf } = PropTypes; +const { func, arrayOf, shape } = PropTypes; LandingPageComponent.propTypes = { flattenedRoutes: arrayOf(propTypes.route).isRequired, - // history.push from withRouter - push: func.isRequired, + // from withRouter + history: shape({ + push: func.isRequired, + }).isRequired, }; export default withRouter(LandingPageComponent); diff --git a/src/containers/LandingPage/LandingPage.test.js b/src/containers/LandingPage/LandingPage.test.js index fc636651..7c30d34e 100644 --- a/src/containers/LandingPage/LandingPage.test.js +++ b/src/containers/LandingPage/LandingPage.test.js @@ -9,7 +9,11 @@ const noop = () => null; describe('LandingPage', () => { it('matches snapshot', () => { const tree = renderShallow( - v} push={noop} flattenedRoutes={[]} /> + v} + history={{ push: noop }} + flattenedRoutes={[]} + /> ); expect(tree).toMatchSnapshot(); }); diff --git a/src/containers/SearchPage/SearchPage.js b/src/containers/SearchPage/SearchPage.js index 614d112d..dc7624d5 100644 --- a/src/containers/SearchPage/SearchPage.js +++ b/src/containers/SearchPage/SearchPage.js @@ -32,7 +32,7 @@ export const SearchPageComponent = props => { listings, location, pagination, - push: historyPush, + history, searchInProgress, searchListingsError, searchParams, @@ -88,7 +88,7 @@ export const SearchPageComponent = props => { const onNextPage = hasNext ? () => { const urlParams = { address, origin, bounds, page: page + 1 }; - historyPush(createResourceLocatorString('SearchPage', flattenedRoutes, {}, urlParams)); + history.push(createResourceLocatorString('SearchPage', flattenedRoutes, {}, urlParams)); } : null; @@ -96,7 +96,7 @@ export const SearchPageComponent = props => { const onPreviousPage = hasPrev ? () => { const urlParams = { address, origin, bounds, page: page - 1 }; - historyPush(createResourceLocatorString('SearchPage', flattenedRoutes, {}, urlParams)); + history.push(createResourceLocatorString('SearchPage', flattenedRoutes, {}, urlParams)); } : null; @@ -152,8 +152,12 @@ SearchPageComponent.propTypes = { totalItems: number, totalPages: number.isRequired, }), - // history.push from withRouter - push: func.isRequired, + + // from withRouter + history: shape({ + push: func.isRequired, + }).isRequired, + searchParams: object, searchInProgress: bool.isRequired, searchListingsError: instanceOf(Error), diff --git a/src/containers/SearchPage/SearchPage.test.js b/src/containers/SearchPage/SearchPage.test.js index efa32478..66762540 100644 --- a/src/containers/SearchPage/SearchPage.test.js +++ b/src/containers/SearchPage/SearchPage.test.js @@ -21,7 +21,9 @@ describe('SearchPageComponent', () => { const props = { flattenedRoutes: [], location: { search: '' }, - push: () => console.log('HistoryPush called'), + history: { + push: () => console.log('HistoryPush called'), + }, tab: 'listings', searchInProgress: false, }; diff --git a/src/containers/Topbar/Topbar.js b/src/containers/Topbar/Topbar.js index 229405c9..f654a88e 100644 --- a/src/containers/Topbar/Topbar.js +++ b/src/containers/Topbar/Topbar.js @@ -11,12 +11,12 @@ const House = () => ; /* eslint-enable react/no-danger */ const Topbar = props => { - const { isAuthenticated, onLogout, push: historyPush } = props; + const { isAuthenticated, onLogout, history } = props; const handleLogout = () => { // History push function is passed to the action to enable // redirect to home when logout succeeds. - onLogout(historyPush); + onLogout(history.push); }; return ( @@ -37,13 +37,16 @@ const Topbar = props => { Topbar.defaultProps = { user: null }; -const { bool, func } = PropTypes; +const { bool, func, shape } = PropTypes; Topbar.propTypes = { isAuthenticated: bool.isRequired, onLogout: func.isRequired, - // history.push prop from withRouter - push: func.isRequired, + + // from withRouter + history: shape({ + push: func.isRequired, + }).isRequired, }; const mapStateToProps = state => ({ isAuthenticated: state.Auth.isAuthenticated }); diff --git a/src/util/routes.js b/src/util/routes.js index e6deccad..7585842f 100644 --- a/src/util/routes.js +++ b/src/util/routes.js @@ -56,8 +56,8 @@ export const matchPathname = (pathname, routesConfiguration) => { return flattenedRoutes.reduce( (matches, route) => { - const { exact = false } = route; - const match = !route.path || matchPath(pathname, route.path, { exact }); + const { path, exact = false } = route; + const match = matchPath(pathname, { path, exact }); if (match) { matches.push({ route, diff --git a/yarn.lock b/yarn.lock index 07f3d060..c4bf88d3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2888,6 +2888,16 @@ history@^4.5.1: value-equal "^0.2.0" warning "^3.0.0" +history@^4.6.0: + version "4.6.1" + resolved "https://registry.yarnpkg.com/history/-/history-4.6.1.tgz#911cf8eb65728555a94f2b12780a0c531a14d2fd" + dependencies: + invariant "^2.2.1" + loose-envify "^1.2.0" + resolve-pathname "^2.0.0" + value-equal "^0.2.0" + warning "^3.0.0" + hmac-drbg@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.0.tgz#3db471f45aae4a994a0688322171f51b8b91bee5" @@ -5400,21 +5410,22 @@ react-redux@^5.0.3: lodash-es "^4.2.0" loose-envify "^1.1.0" -react-router-dom@4.0.0-beta.6: - version "4.0.0-beta.6" - resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-4.0.0-beta.6.tgz#bdbd8f2fea3def52970735778db03b24cc082a02" +react-router-dom@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-4.0.0.tgz#4fa4418e14b8cfc5bcc0bdea0c4083fb8c2aef10" dependencies: history "^4.5.1" - react-router "^4.0.0-beta.6" + react-router "^4.0.0" -react-router@^4.0.0-beta.6: - version "4.0.0-beta.6" - resolved "https://registry.yarnpkg.com/react-router/-/react-router-4.0.0-beta.6.tgz#561ac0bf1929960813bf201319ff85d821d5547b" +react-router@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/react-router/-/react-router-4.0.0.tgz#6532075231f0bb5077c2005c1d417ad6165b3997" dependencies: - history "^4.5.1" + history "^4.6.0" invariant "^2.2.2" loose-envify "^1.3.1" path-to-regexp "^1.5.3" + warning "^3.0.0" react-side-effect@^1.1.0: version "1.1.0"