redux
是什么、有什么作用,解决什么问题,如果你还不知道,请先去这里: redux中文文档
下面的文章适合对redux有一定理解和使用经验的人
项目github地址:github.com/wangweiange…
如果你觉得对你有帮助的话记得给我一个star 呢
combineReducers是redux的一个核心辅助函数,把多个reducer 合并成一个reducer集合,按key值来区分各个reducer,最终大致数据结构如下:
{
reducer1: ...
reducer2: ...
}复制代码
最直白的注解,就是干了下面这个事情返回了combination函数。
//有三个函数
let initstate={number:1}
function a(state=initstate,action){
...
}
function b(state=initstate,action){
...
}
function c(state=initstate,action){
...
}
//调用combineReducers方法
const reducers = combineReducers({
a,
b,
c
})
//得到combination这个function
function combination(state = {}, action){
const nextState = {
a:{number:1},
b:{number:1},
c:{number:1}
}
return nextState
}
//调用的得到 nextState 最终赋值给 createStore方法里面的currentState变量
currentState = combination(currentState,action)复制代码
下面让我们来看看源码,我对源码进行了很大的精简,代码如下:
export default function combineReducers(reducers) {
const finalReducers = reducers
const finalReducerKeys = Object.keys(finalReducers)
return function combination(state = {}, action) {
let hasChanged = false
const nextState = {}
for (let i = 0; i < finalReducerKeys.length; i++) {
const key = finalReducerKeys[i]
const reducer = finalReducers[key]
const previousStateForKey = state[key]
const nextStateForKey = reducer(previousStateForKey, action)
nextState[key] = nextStateForKey
hasChanged = hasChanged || nextStateForKey !== previousStateForKey
}
return hasChanged ? nextState : state
}
}复制代码
真正的核心代码就这么多,完全可以自己写一个。
给一段测试代码,根据这段代码去理解上面的combineReducers函数
const initialStateHome = {
home:10,
cart:20
}
function home (state = initialStateHome, action) {
switch (action.type) {
case ADD_SOME_OME:
return { ...state, home: action.number }
default:
return state
}
}
function cart (state = initialStateHome, action) {
switch (action.type) {
case GET_CART_NUMBER:
return { ...state, cart: action.number }
default:
return state
}
}
const reducers = combineReducers({
home,
cart,
})复制代码
我们根据这个测试案例来分析combineReducers函数:
export default function combineReducers(reducers) {
/*
finalReducers的值为
{
home:function home(state = initialStateHome, action){...},
cart:function cart(state = initialStateHome, action){...}
}
*/
const finalReducers = reducers
//finalReducerKeys 的值为: ['home','cart']
const finalReducerKeys = Object.keys(finalReducers)
/*
这里假设调用了
store.dispatch({
type: 'ADD_SOME_OME',
number: 30
})
*/
return function combination(state = {}, action) {
/*
此时 action = {type: 'ADD_SOME_OME',number: 30}
state 的值应该为: {home:10,cart:20}
*/
let hasChanged = false
const nextState = {}
for (let i = 0; i < finalReducerKeys.length; i++) {
const key = finalReducerKeys[i]
const reducer = finalReducers[key]
const previousStateForKey = state[key]
/*
这里会匹配到 type: 'ADD_SOME_OME' 也就 home 函数里面的 switch 语句
匹配之后会得到的值为:nextStateForKey = {home:30}
而此时的 previousStateForKey = 10
*/
const nextStateForKey = reducer(previousStateForKey, action)
//给nextState 赋值 也就是: nextState['home'] = {home:30}
nextState[key] = nextStateForKey
//很明显 nextStateForKey !== previousStateForKey 值为 true
hasChanged = hasChanged || nextStateForKey !== previousStateForKey
}
//因此取 nextState
return hasChanged ? nextState : state
}
}复制代码
这段代码很好理解,你也可以查看我github源码中 mean-combineReducers.js,和combineReducers.js 有可运行的测试案例,有详细的代码说明。
备注:理解此段代码需要理解透createStore.js, 其中以下代码需要注意到,最终会在这里调用:
接下来我们进入到redux
的高阶方法 applyMiddleware
redux v3.7.2源码解读与学习之 applyMiddleware