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

Commit 4a3af3a

Browse files
committed
Handle routing state and replace
1 parent d908741 commit 4a3af3a

File tree

2 files changed

+48
-13
lines changed

2 files changed

+48
-13
lines changed

package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,5 +28,8 @@
2828
"babel-cli": "^6.1.2",
2929
"babel-plugin-transform-object-assign": "^6.0.14",
3030
"babel-preset-es2015": "^6.1.2"
31+
},
32+
"dependencies": {
33+
"deep-equal": "^1.0.1"
3134
}
3235
}

src/index.js

Lines changed: 45 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,45 @@
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, noRouterUpdate) {
10+
function updatePath(path, state, noRouterUpdate) {
1011
return {
1112
type: UPDATE_PATH,
1213
path: path,
13-
noRouterUpdate: noRouterUpdate
14+
replace: false,
15+
noRouterUpdate: !!noRouterUpdate
16+
}
17+
}
18+
19+
function replacePath(path, state, noRouterUpdate) {
20+
return {
21+
type: UPDATE_PATH,
22+
path: path,
23+
replace: true,
24+
noRouterUpdate: !!noRouterUpdate
1425
}
1526
}
1627

1728
// Reducer
1829

19-
const initialState = typeof window === 'undefined' ? {} : {
20-
path: locationToString(window.location)
30+
const initialState = {
31+
path: undefined,
32+
state: undefined,
33+
replace: false,
34+
noRouterUpdate: true
2135
};
2236

2337
function update(state=initialState, action) {
2438
if(action.type === UPDATE_PATH) {
2539
return Object.assign({}, state, {
2640
path: action.path,
41+
state: action.state,
42+
replace: action.replace,
2743
noRouterUpdate: action.noRouterUpdate
2844
});
2945
}
@@ -32,8 +48,8 @@ function update(state=initialState, action) {
3248

3349
// Syncing
3450

35-
function locationToString(location) {
36-
return location.pathname + location.search + location.hash;
51+
function locationsAreEqual(a, b) {
52+
return a.path === b.path && deepEqual(a.state, b.state);
3753
}
3854

3955
function syncReduxAndRouter(history, store, selectRouterState = SELECT_STATE) {
@@ -46,12 +62,24 @@ function syncReduxAndRouter(history, store, selectRouterState = SELECT_STATE) {
4662
);
4763
}
4864

65+
let historyLocation = {};
66+
4967
const unsubscribeHistory = history.listen(location => {
68+
historyLocation = {
69+
path: history.createPath(location),
70+
state: location.state
71+
};
72+
73+
const routing = getRouterState();
74+
5075
// Avoid dispatching an action if the store is already up-to-date,
5176
// even if `history` wouldn't do anything if the location is the same
52-
if(getRouterState().path !== locationToString(location)) {
53-
store.dispatch(updatePath(locationToString(location)));
54-
}
77+
if(locationsAreEqual(routing, historyLocation)) return;
78+
79+
// Initial state, update store with the current location but skip routing
80+
const noRouterUpdate = routing.path == null;
81+
82+
store.dispatch(updatePath(historyLocation.path, historyLocation.state, noRouterUpdate));
5583
});
5684

5785
const unsubscribeStore = store.subscribe(() => {
@@ -61,9 +89,12 @@ function syncReduxAndRouter(history, store, selectRouterState = SELECT_STATE) {
6189
// `noRouterUpdate` flag can be set to avoid updating altogether,
6290
// which is useful for things like loading snapshots or very special
6391
// edge cases.
64-
if(routing.path !== locationToString(window.location) &&
65-
!routing.noRouterUpdate) {
66-
history.pushState(null, routing.path);
92+
if (locationsAreEqual(routing, historyLocation) || routing.noRouterUpdate) return;
93+
94+
if (routing.replace) {
95+
history.replaceState(routing.state, routing.path);
96+
} else {
97+
history.pushState(routing.state, routing.path);
6798
}
6899
});
69100

@@ -76,6 +107,7 @@ function syncReduxAndRouter(history, store, selectRouterState = SELECT_STATE) {
76107
module.exports = {
77108
UPDATE_PATH,
78109
updatePath,
110+
replacePath,
79111
syncReduxAndRouter,
80112
routeReducer: update,
81113
};

0 commit comments

Comments
 (0)