Skip to content
This repository was archived by the owner on Oct 26, 2018. It is now read-only.

Commit bbe5071

Browse files
committed
Merge pull request #38 from kjbekkelund/routing-state-and-replace
Handle routing state and replace
2 parents 0941951 + 2a65890 commit bbe5071

File tree

3 files changed

+278
-52
lines changed

3 files changed

+278
-52
lines changed

package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,5 +36,8 @@
3636
"isparta": "^4.0.0",
3737
"mocha": "^2.3.4",
3838
"redux": "^3.0.4"
39+
},
40+
"dependencies": {
41+
"deep-equal": "^1.0.1"
3942
}
4043
}

src/index.js

Lines changed: 46 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,59 @@
1+
const deepEqual = require('deep-equal');
12

2-
// constants
3+
// Constants
34

45
const UPDATE_PATH = "@@router/UPDATE_PATH";
56
const SELECT_STATE = state => state.routing;
67

78
// Action creator
89

9-
function updatePath(path, avoidRouterUpdate) {
10+
function pushPath(path, state, opts) {
11+
opts = opts || {};
1012
return {
1113
type: UPDATE_PATH,
1214
path: path,
13-
avoidRouterUpdate: !!avoidRouterUpdate
15+
state: state,
16+
replace: false,
17+
avoidRouterUpdate: !!opts.avoidRouterUpdate
18+
};
19+
}
20+
21+
function replacePath(path, state, opts) {
22+
opts = opts || {};
23+
return {
24+
type: UPDATE_PATH,
25+
path: path,
26+
state: state,
27+
replace: true,
28+
avoidRouterUpdate: !!opts.avoidRouterUpdate
1429
}
1530
}
1631

1732
// Reducer
1833

1934
const initialState = {
2035
changeId: 1,
21-
path: (typeof window !== 'undefined') ?
22-
locationToString(window.location) :
23-
'/'
36+
path: undefined,
37+
state: undefined,
38+
replace: false
2439
};
2540

2641
function update(state=initialState, action) {
2742
if(action.type === UPDATE_PATH) {
2843
return Object.assign({}, state, {
2944
path: action.path,
30-
changeId: state.changeId + (action.avoidRouterUpdate ? 0 : 1)
45+
changeId: state.changeId + (action.avoidRouterUpdate ? 0 : 1),
46+
state: action.state,
47+
replace: action.replace
3148
});
3249
}
3350
return state;
3451
}
3552

3653
// Syncing
3754

38-
function locationToString(location) {
39-
return location.pathname + location.search + location.hash;
55+
function locationsAreEqual(a, b) {
56+
return a.path === b.path && deepEqual(a.state, b.state);
4057
}
4158

4259
function syncReduxAndRouter(history, store, selectRouterState = SELECT_STATE) {
@@ -51,24 +68,31 @@ function syncReduxAndRouter(history, store, selectRouterState = SELECT_STATE) {
5168
}
5269

5370
const unsubscribeHistory = history.listen(location => {
54-
const routePath = locationToString(location);
71+
const route = {
72+
path: history.createPath(location),
73+
state: location.state
74+
};
75+
76+
// Avoid dispatching an action if the store is already up-to-date,
77+
// even if `history` wouldn't do anything if the location is the same
78+
if(locationsAreEqual(getRouterState(), route)) return;
5579

56-
// Avoid dispatching an action if the store is already up-to-date
57-
if(getRouterState().path !== routePath) {
58-
store.dispatch(updatePath(routePath, { avoidRouterUpdate: true }));
59-
}
80+
store.dispatch(pushPath(route.path, route.state, { avoidRouterUpdate: true }));
6081
});
6182

6283
const unsubscribeStore = store.subscribe(() => {
6384
const routing = getRouterState();
6485

65-
// Only update the router once per `updatePath` call. This is
86+
// Only update the router once per `pushPath` call. This is
6687
// indicated by the `changeId` state; when that number changes, we
67-
// should call `pushState`.
68-
if(lastChangeId !== routing.changeId) {
69-
lastChangeId = routing.changeId;
70-
history.pushState(null, routing.path);
71-
}
88+
// should update the history.
89+
if(lastChangeId === routing.changeId) return;
90+
91+
lastChangeId = routing.changeId;
92+
93+
const method = routing.replace ? 'replaceState' : 'pushState';
94+
95+
history[method](routing.state, routing.path);
7296
});
7397

7498
return function unsubscribe() {
@@ -79,7 +103,8 @@ function syncReduxAndRouter(history, store, selectRouterState = SELECT_STATE) {
79103

80104
module.exports = {
81105
UPDATE_PATH,
82-
updatePath,
106+
pushPath,
107+
replacePath,
83108
syncReduxAndRouter,
84109
routeReducer: update
85110
};

0 commit comments

Comments
 (0)