acdlite / acdlite/redux-router

Order of other middleware

Open
#87 9 comments 0 reactions 0 assignees View on GitHub
bug
Dominant language
JavaScript
Stars
2.3k
Forks
194
PR merge metrics
No merged PRs in 30d

Description

Not sure if this is just a gotcha to be documented or an actual issue...

**TLDR** I needed to put `thunk` and `promise` middleware before the router and I had to put my `logger` middleware before AND after the router (and make sure I only log the same action once). This is due to the router `historyMiddleware` not calling next() (which is probably correct).
## Before

I'm creating my store with the following code. With my middleware chain before the router, everything works fine except I don't get any logging of `@@reduxReactRouter/historyAPI` actions, which is totally predictable because if the historyMiddleware catches one of those it triggers a state change and the rest of the middleware does not fire. This is not a problem per-se but my preference is to log **all** actions during development so I can really see whats going on in the app.

**store.js**

``` js
import {createStore, applyMiddleware, compose} from 'redux'
import {reduxReactRouter} from 'redux-router'
import createBrowserHistory from 'history/lib/createBrowserHistory'
import transducers from './transducers'
import reducers from './reducers'
import middleware from './middleware'

let devTools = () => next => (reducer, initialState) => next(reducer, initialState) // noop
if ((process.env.NODE_ENV === 'development') && (window.localStorage.getItem('DEVTOOLS') === 'enabled')) {
devTools = require('redux-devtools').devTools
}

const initialState = {}

const store = compose(
applyMiddleware.apply(null, middleware),
reduxReactRouter({createHistory: createBrowserHistory}),
devTools()
)(createStore)(transducers(reducers), initialState)

// Enable Webpack hot module replacement for reducers.
if (module.hot) {
module.hot.accept('./reducers', () => {
const nextRootReducer = require('./reducers/index')
store.replaceReducer(transducers(nextRootReducer))
})
}

export default store
```

**transducers/index.js**

``` js
import {compose} from 'redux'
import history from './history'

export default compose(
history
)
```

**reducers/index.js**

``` js
import {combineReducers} from 'redux'
import account from './account'
import comic from './comic'
import feed from './feed'
import notifications from './notifications'
import router from './router'

const reducers = {
account,
comic,
feed,
notifications,
router
}
const combined = combineReducers(reducers)
```

**middleware/index.js**

``` js
import logger from './logger'
import crashReporter from './crashReporter'
import promise from './promise'
import thunk from './thunk'
import validationErrors from './validationErrors'
import {batchedUpdatesMiddleware} from 'redux-batched-updates'

const middleware = [
crashReporter,
promise,
thunk,
logger,
validationErrors,
batchedUpdatesMiddleware
]

export default middleware
```
## After

To accommodate my logging needs, I split my middleware into a 'before' chain and an 'after' chain like so:

**middleware/_before.js**

``` js
import crashReporter from './crashReporter'
import promise from './promise'
import thunk from './thunk'
import logger from './logger'

const middleware = [
crashReporter,
promise,
thunk,
logger
]

export default middleware
```

**middleware/_after.js**

``` js
import logger from './logger'
import validationErrors from './validationErrors'
import {batchedUpdatesMiddleware} from 'redux-batched-updates'

const middleware = [
logger,
validationErrors,
batchedUpdatesMiddleware
]

export default middleware
```

**middleware/logger.js**
I added a check to make sure the same action doesn't get logged twice.

**store.js (changes)**

``` js
const store = compose(
applyMiddleware.apply(null, beforeMiddleware),
reduxReactRouter({createHistory: createBrowserHistory}),
applyMiddleware.apply(null, afterMiddleware),
devTools()
)(createStore)(transducers(reducers), initialState)
```

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.