From e82a7750491e8315d7db9ad719c2c0954c1f4511 Mon Sep 17 00:00:00 2001 From: Kimmo Puputti Date: Wed, 25 Oct 2017 17:01:57 +0300 Subject: [PATCH] Add Routing duck to track location changes --- src/Routes.js | 9 +++++++++ src/ducks/Routing.duck.js | 32 ++++++++++++++++++++++++++++++++ src/ducks/index.js | 8 +++++--- 3 files changed, 46 insertions(+), 3 deletions(-) create mode 100644 src/ducks/Routing.duck.js diff --git a/src/Routes.js b/src/Routes.js index 40b28786..83963a9a 100644 --- a/src/Routes.js +++ b/src/Routes.js @@ -5,6 +5,7 @@ import { connect } from 'react-redux'; import { Switch, Route, withRouter } from 'react-router-dom'; import { NotFoundPage } from './containers'; import { NamedRedirect } from './components'; +import { locationChanged } from './ducks/Routing.duck'; import * as propTypes from './util/propTypes'; import * as log from './util/log'; @@ -34,10 +35,17 @@ const callLoadData = props => { } }; +const handleLocationChanged = (dispatch, location) => { + const { pathname, search, hash } = location; + const canonicalUrl = `${pathname}${search}${hash}`; + dispatch(locationChanged(location, canonicalUrl)); +}; + class RouteComponentRenderer extends Component { componentDidMount() { // Calling loadData on initial rendering (on client side). callLoadData(this.props); + handleLocationChanged(this.props.dispatch, this.props.location); } componentWillReceiveProps(nextProps) { @@ -45,6 +53,7 @@ class RouteComponentRenderer extends Component { // This makes it possible to use loadData as default client side data loading technique. // However it is better to fetch data before location change to avoid "Loading data" state. callLoadData(nextProps); + handleLocationChanged(nextProps.dispatch, nextProps.location); } render() { diff --git a/src/ducks/Routing.duck.js b/src/ducks/Routing.duck.js new file mode 100644 index 00000000..0172b05e --- /dev/null +++ b/src/ducks/Routing.duck.js @@ -0,0 +1,32 @@ +// ================ Action types ================ // + +export const LOCATION_CHANGED = 'app/Routing/LOCATION_CHANGED'; + +// ================ Reducer ================ // + +const initialState = { + currentLocation: null, + currentCanonicalUrl: null, +}; + +export default function routingReducer(state = initialState, action = {}) { + const { type, payload } = action; + switch (type) { + case LOCATION_CHANGED: + return { + ...state, + currentLocation: payload.location, + currentCanonicalUrl: payload.canonicalUrl, + }; + + default: + return state; + } +} + +// ================ Action creators ================ // + +export const locationChanged = (location, canonicalUrl) => ({ + type: LOCATION_CHANGED, + payload: { location, canonicalUrl }, +}); diff --git a/src/ducks/index.js b/src/ducks/index.js index 183c2afa..0f451fe7 100644 --- a/src/ducks/index.js +++ b/src/ducks/index.js @@ -6,20 +6,22 @@ import { reducer as form } from 'redux-form'; import Auth from './Auth.duck'; +import EmailVerification from './EmailVerification.duck'; import FlashNotification from './FlashNotification.duck'; import LocationFilter from './LocationFilter.duck'; +import Routing from './Routing.duck'; import UI from './UI.duck'; import marketplaceData from './marketplaceData.duck'; import user from './user.duck'; -import EmailVerification from './EmailVerification.duck'; export { - form, Auth, + EmailVerification, FlashNotification, LocationFilter, + Routing, UI, + form, marketplaceData, user, - EmailVerification, };