在《React高级篇(一)从Flux到Redux,react-redux》文章中贴过一张redux单向数据流的图,但是,从action到reduer,其实还缺少了不少环节。
举个例子,如果发起一个异步动作(比如网络请求),该如何处理?redux单向数据流一定是同步的,碰上异步Action,必须将其转为同步Action,才可以继续走下去,否则事件会被丢失。
再比如,如果需要给每个Action都要打Log,那么,是否有个节点可以统一处理?
于是,store enhance(middleware是它的特殊实现)出现了,Action到达reducer之前,会经过一系列的enhancer处理看下图:
redux flow.png复习:Store的创建方式
createStore(reducer, [preloadedState], [enhancer])
第三个参数即是enhancer
。
创建Store的enhancer
一个store对象中包含下列接口:
- dispatch
- subscribe
- getState
- replaceReducer
一般来说,自定义enhancer都是针对上述接口做能力增强,比如提供日志功能的logEnhancer,定义如下:
const logEnhancer = (createStore) => (reducer, preloadedState, enhancer) => (
const store= createStore(reducer, preloadedState, enhancer);
const originalDispatch = store.dispatch;
store.dispatch = (action) => {
console.log('dispatch action:’,action);
originalDispatch(action);
return store;
};
增强器通常都使用这样的模式,将store上某个函数的引用存下来,给这个函数一个新的实现,但是在完成增强功能之后,还是要调用原有的函数,保持原有的功能。
store enhancer和middleware的关系?
middleware本身就是一个store enhancer,它专门负责增强redux.dispatch()
方法。middleware源码示意如下:
export default function middleware(...middlewares) {
return createStore => (...args) =>
{ // 省略 return { ...store, dispatch }
}
}
注意:middleware应该置于enhancer队列的最前排。
常用的middleware是处理异步请求的redux-thunk。
对于异步工作流,一定要用dispatch函数派发,而不是使用next函数,这样,异步工作流才可以被所有中间件处理,否则,它只能被当前位置之后的中间件处理。
后记
讲redux-thunk相关的文章非常多,不再累述。
参考文章:浅析Redux 的 store enhancer,书籍-《深入浅出react和redux》
网友评论