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

Commit 7cdc72a

Browse files
committed
Extract the action creators and middleware.
Getting the easy parts done first.
1 parent cb2d7f0 commit 7cdc72a

File tree

3 files changed

+49
-111
lines changed

3 files changed

+49
-111
lines changed

src/actions.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/**
2+
* This action type will be dispatched by the history actions below.
3+
* If you're writing a middleware to watch for navigation events, be sure to
4+
* look for actions of this type.
5+
*/
6+
export const UPDATE_LOCATION = '@@router/UPDATE_LOCATION'
7+
8+
function updateLocation(method) {
9+
return (...args) => ({
10+
type: UPDATE_LOCATION,
11+
payload: { method, args }
12+
})
13+
}
14+
15+
/**
16+
* These actions correspond to the history API.
17+
* The associated routerMiddleware will capture these events before they get to
18+
* your reducer and reissue them as the matching function on your history.
19+
*/
20+
export const push = updateLocation('push')
21+
export const replace = updateLocation('replace')
22+
export const go = updateLocation('go')
23+
export const goBack = updateLocation('goBack')
24+
export const goForward = updateLocation('goForward')
25+
26+
export const routeActions = { push, replace, go, goBack, goForward }

src/index.js

Lines changed: 6 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -1,112 +1,7 @@
1-
// Constants
1+
export {
2+
UPDATE_LOCATION,
3+
push, replace, go, goBack, goForward,
4+
routeActions
5+
} from './actions'
26

3-
export const TRANSITION = '@@router/TRANSITION'
4-
export const UPDATE_LOCATION = '@@router/UPDATE_LOCATION'
5-
6-
const SELECT_LOCATION = state => state.routing.location
7-
8-
function transition(method) {
9-
return (...args) => ({
10-
type: TRANSITION,
11-
payload: { method, args }
12-
})
13-
}
14-
15-
export const push = transition('push')
16-
export const replace = transition('replace')
17-
export const go = transition('go')
18-
export const goBack = transition('goBack')
19-
export const goForward = transition('goForward')
20-
21-
export const routeActions = { push, replace, go, goBack, goForward }
22-
23-
function updateLocation(location) {
24-
return {
25-
type: UPDATE_LOCATION,
26-
payload: location
27-
}
28-
}
29-
30-
// Reducer
31-
32-
const initialState = {
33-
location: undefined
34-
}
35-
36-
export function routeReducer(state = initialState, { type, payload: location }) {
37-
if (type !== UPDATE_LOCATION) {
38-
return state
39-
}
40-
41-
return { ...state, location }
42-
}
43-
44-
// Syncing
45-
46-
export function syncHistory(history) {
47-
let unsubscribeHistory, currentKey, unsubscribeStore
48-
let connected = false, syncing = false
49-
50-
history.listen(location => { initialState.location = location })()
51-
52-
function middleware(store) {
53-
unsubscribeHistory = history.listen(location => {
54-
currentKey = location.key
55-
if (syncing) {
56-
// Don't dispatch a new action if we're replaying location.
57-
return
58-
}
59-
60-
store.dispatch(updateLocation(location))
61-
})
62-
63-
connected = true
64-
65-
return next => action => {
66-
if (action.type !== TRANSITION || !connected) {
67-
return next(action)
68-
}
69-
70-
const { payload: { method, args } } = action
71-
history[method](...args)
72-
}
73-
}
74-
75-
middleware.listenForReplays =
76-
(store, selectLocationState = SELECT_LOCATION) => {
77-
const getLocationState = () => selectLocationState(store.getState())
78-
const initialLocation = getLocationState()
79-
80-
unsubscribeStore = store.subscribe(() => {
81-
const location = getLocationState()
82-
83-
// If we're resetting to the beginning, use the saved initial value. We
84-
// need to dispatch a new action at this point to populate the store
85-
// appropriately.
86-
if (location.key === initialLocation.key) {
87-
history.replace(initialLocation)
88-
return
89-
}
90-
91-
// Otherwise, if we need to update the history location, do so without
92-
// dispatching a new action, as we're just bringing history in sync
93-
// with the store.
94-
if (location.key !== currentKey) {
95-
syncing = true
96-
history.transitionTo(location)
97-
syncing = false
98-
}
99-
})
100-
}
101-
102-
middleware.unsubscribe = () => {
103-
unsubscribeHistory()
104-
if (unsubscribeStore) {
105-
unsubscribeStore()
106-
}
107-
108-
connected = false
109-
}
110-
111-
return middleware
112-
}
7+
export routerMiddleware from './middleware'

src/middleware.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import UPDATE_LOCATION from './actions'
2+
3+
/**
4+
* This middleware captures UPDATE_LOCATION actions to redirect to the
5+
* provided history object. This will prevent these actions from reaching your
6+
* reducer or any middleware that comes after this one.
7+
*/
8+
export default function routerMiddleware(history) {
9+
return () => next => action => {
10+
if (action.type !== UPDATE_LOCATION) {
11+
return next(action)
12+
}
13+
14+
const { payload: { method, args } } = action
15+
history[method](...args)
16+
}
17+
}

0 commit comments

Comments
 (0)