acdlite / acdlite/redux-router

Order of other middleware

未关闭
#87 9 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看
bug
主要语言
JavaScript
星标
2.3k
派生
194
PR 合并指标
30 天内没有已合并 PR

描述

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)
```

贡献指南

这个仓库没有索引到贡献指南

调研方向

The issue is about middleware ordering in a Redux store with redux-router. Look at the store.js file to see how middleware is applied before and after the router. The logger middleware is in both before and after chains to capture all actions. Check the redux-router source to understand why historyMiddleware doesn't call next(). Start by examining the middleware chain and the router's handling of actions like @@reduxReactRouter/historyAPI.

由索引模型根据 Issue 内容生成。

评估

技术栈
javascript, redux
领域
backend-api-design, tooling
Issue 类型
缺陷
难度
3/5
预计耗时
1-2 天
活跃度
停滞
描述清晰度
基本清楚
新手友好度
45/100

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。