前面一篇我们介绍了最最基础的Redux的工作流程,但是有些问题是没有解决的?
下面我们就针对几个问题渐渐深入探讨Redux...
(1):Reducer函数负责生产state,state包含所有的数据,所以生成Reducer必然十分庞大,那么如何解决这个问题?
假设action1只影响state的属性A,action2只影响state的属性B,action3只影响state的属性C。A、B、C三个属性之间没有联系,那么我们可以将Reducer函数拆分成三个函数,然后将拆分的函数组后合并成Reducer。Redux也提供了combineReducers方法,用于合并所有的拆分函数。
(2):基础的Redux的工作流程都是同步的,每当dispatch action时候,state会被立即更新,那么Redux是如何处理异步数据流的?
1:处理异步数据也就是在Action发出以后,执行异步操作结束后自动执行Reducer。那么就需要中间件(middleware),用于执行异步操作。
首先,我们在那个环节添加中间环节去处理异步数据流?
(1)Reducer、create Action纯函数不适合承担其他功能,因为理论上,纯函数不能进行读写操作。
(2)Action 存储对象的数据。消息载体,自己不能进行操作。
所以只能在store.dispatch()方法中添加中间环节这个步骤。那么就需要对于dispatch这个方法进行改造。
let next = store.dispatch;
store.dispatch = function dispatchAndElse(action) {
//在真正dispatch前可以做一些事情
next(action);
//在真正发送Action后做一些事情
}
所以中间件就是一个函数,对store.dispatch
方法进行了改造,在发出 Action 和执行 Reducer 这两步之间,添加了其他功能。
2:常用的中间件都有现成的,引用即可。
3:如何使用中间件?
Redux提供了applyMiddleware这个方法,将所有的中间件组成一个数组,依次执行。
源码如下:
export default function applyMiddleware(...middlewares) {
return (createStore) => (...args) => {
const store = createStore(...args)
let dispatch = store.dispatch
let chain = []
const middlewareAPI = {
getState: store.getState,
dispatch: (...args) => dispatch(...args)
}
chain = middlewares.map(middleware => middleware(middlewareAPI))
dispatch = compose(...chain)(store.dispatch)
return {
...store,
dispatch
}
}
}
compose函数为:
export default function compose(...funcs) {
if (funcs.length === 0) {
return arg => arg
}
if (funcs.length === 1) {
return funcs[0]
}
return funcs.reduce((a, b) => (...args) => a(b(...args)))
}
通过上述函数可以看出所有的中间件被放在一个数组chain,然后嵌套执行,最后执行store.dispatch。
这里并没有很详细的介绍Redux,只是给出了Redux所要了解的几个重要问题,以及整体的概念,如果想要了解更深可以直接看源码,源码不是很长。
本文来自网易实践者社区,经作者王海玲授权发布。