蘑菇小姐会开花

redux middleware

wrapping dispatch() to log actions

logger 中间件
函数addLoggingToDispatch,接受一个store为参数,返回一个新的dispatch方法,将store.dispatch覆盖,并log出相对应的action和state信息。

the addLoggingToDispatch function takes the dispatch from the store and returns a new version of dispatch that logs every action and the state

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
const addLoggingToDispatch = (store) => {
const next = store.dispatch;
if(!console.group) {
return next
}
// 返回一个新的dispatch方法
// 在store.dispatch的基础上,log一些信息
return (action) => {
console.group(action.type);
console.log('%c prev state', 'color: gray', store.getState());
console.log('%c action', 'color: blue', action);
const returnValue = next(action);
console.log('%c next state', store.getState());
console.groupEnd(action.type);
return returnValue;
}
}

<!--引用logger中间件-->
const configureStore = () => {
const store = createStore(todoApp)

if(process.env.NODE_ENV !== 'production') {
store.dispatch = addLoggingToDispatch(store)
}

return store
}

wrapping dispatch() to recognize promise

promise中间件
redux 只能dispatch普通的对象,不能dispatch promise
函数addLoggingToDispatch,接受一个store为参数,返回一个新的能处理promise的dispatch方法,。

a function addPromiseSupport() that takes the store and returns a version of dispatch that supports promises.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// promise action example
// api.fetchTodos = new Promise(resolve => setTimeout(resolve, ms)).then(() => {})
const fetchTodos = filter => api.fetchTodos(filter).then(response => receiveTodos(filter, response))

const addPromiseSupportToDispatch = (store) => {
const next = store.dispatch;
return (action) => {
if(typeof action.then === 'function') {
return action.then(next);
}
return next(action)
}
}

<!--引用promise中间件-->
const configureStore = () => {
const store = createStore(todoApp)

// if(process.env.NODE_ENV !== 'production') {
// store.dispatch = addLoggingToDispatch(store)
// }

store.dispatch = addPromiseSupportToDispatch(store)
return store
}

the middleware chain

函数wrapDispatchWithMiddlewares,接受store和middlrwares[array]两个参数。

a function wrapDispatchWithMiddlewares() that takes the store as the first argument, and the array of middlewares as the second.

1
2
3
4
5
const wrapDispatchWithMiddlewares = (store, middlewares) => {
middlewares.forEach(middleware =>
store.dispatch = middleware(store)
)
}

修改addLoggingToDispatch()addPromiseSupportToDispatch()
将next作为参数提取出来

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
const logger = (store) => (next) => {
if(!console.group) {
return next
}
return (action) => {
console.group(action.type);
console.log('%c prev state', 'color: gray', store.getState());
console.log('%c action', 'color: blue', action);
const returnValue = next(action);
console.log('%c next state', store.getState());
console.groupEnd(action.type);
return returnValue;
}
}

const promise = (store) => (next) => (action) => {
if(typeof action.then === 'function') {
return action.then(next);
}
return next(action)
}

再修改wrapDispatchWithMiddlewares()
中间件的调用为store.dispatch = middleware(store)(store.dispatch)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
const wrapDispatchWithMiddlewares = (store, middlewares) => {
// 复制&颠倒middlewares
middlewares.slice().reverse().forEach(middleware =>
store.dispatch = middleware(store)(store.dispatch)
)
}

const configureStore = () => {
const store = createStore(todoApp)
const middlewares = [promise]

if(process.env.NODE_ENV !== 'production') {
middlewares.push(logger)
}

wrapDispatchWithMiddlewares(store, middlewares)

return store
}

Dispatching Actions Asynchronously with thunks

thunk中间件支持dispatch thunks,和其他的中间件一样,它接受store、next、action作为参数。如果action是一个函数,则将dispatch传给action,直接调用store.dispatch(action),否则返回next(action)

Functions returned from other functions are often called thunks

1
2
3
4
5
6
7
8
9
10
11
12
// thunk action
const toggleTodo = id => (dispatch, getState) => {
return api.toggleTodo(id).then(response => {
dispatch({
type: 'TOGGLE_TODO',
response: normalize(response, schema.todo)
})
})
}

const thunk = store => next => action =>
typeof action === 'function' ? action(store.dispatch, store.getState) : next(action)
坚持原创技术分享,您的支持将鼓励我继续创作!