redux的createStore第二参数preloadedState(初始化state)是如何控制单一或通过combineReducer组合生成的reducer中手动加的state的默认值是否生效的

createStore中的第二个参数preloadedState是可选的,如果省略第二个参数preloadedState,直接设置第三个参数composeEnhancers(用于添加中间件的),那么createStore内部会进行处理,将preloadedState设置为undefined。或者第二个参数和第三个参数都没有的话,preloadedState也是undefined
const store = createStore(reducerz,{a:55555},composeEnhancers(
applyMiddleware(thunk)
));
createStore()函数运行时会先在内部进行一次初始化的dispatch,来使state有一个初始值,这个初始化的过程中会 将preloadedState、单一reducer或者combineReducer生成的reducer、reducer中的参数state的默认值三者之间进行处理,得出一个初始化的state。

1.单一reducer:
<1> 有preloadedState:
const store = createStore(reducer1,{open:55555},composeEnhancers(
applyMiddleware(thunk)
));
reducer1 = (state={count:0},action)=>{
}
上例中的preloadedState = {open:55555}这个参数,那么preloadedState会在初始化的过程中出入reducer1中,从而覆盖掉reducer1中参数state的默认值{count:0},使得reducer1中的state初始化时为 {open:55555}。
<2> 无preloadedState:
const store = createStore(reducer1,composeEnhancers(
applyMiddleware(thunk)
));
reducer2 = (state={count:0},action)=>{
}
上例中的preloadedState = undefined,那么createStore在初始化的过程中显式的将一个undefined传入reducer1中,根据es6函数参数的默认值相关知识可以知道,当显式的传入undefined时 ,参数state的默认值{count:0}会生效,使得reducer1中的state初始化时为 {count:0}。
2. combineReducer()多个reducer混合
reducer = combineReducers({a:reducer1,b:reducer2})
combineReducers的原理:
combineReducers = reducers => {
return (state = {}, action) => {
return Object.keys(reducers).reduce(
(nextState, key) => {
nextState[key] = reducers[key](state[key], action);
return nextState;
},
{}
);
};
};
所以生成的reducer是一个函数,这个函数返回的是一个包含各个key的大state。
<1> 有preloadedState:
const store = createStore(reducer,{a:{count:11}},composeEnhancers(
applyMiddleware(thunk)
));
reducer1 = (state={count:0},action)=>{
}
reducer2 = (state={count:0},action)=>{
}
有preloadedState时,preloadedState中的key必须与combineReducers中传入的对象的key一样,否则通过combineReducers的原理我们可以看到这个preloadedState还是不会覆盖掉各个子reducer中的state的。
preloadedState会首先替换combineReducers()生成的大的reducer中state设置的默认值空对象{},然后通过combineReducers()中传入的对象的key在 preloadedState找,看preloadedState有没有这个key,如果有的话,就会将preloadedState中的这个key的所对应的值传入到对应的子reducer中,从而将子reducer中的state的默认值替换掉。如果preloadedState中没有这个key,那么传入子reducer中的就是undefined,那么子reducer中state的默认值就会生效。
上例中我们的preloadedState是{a:{count:11}},那么初始化中会将子reducer1中的state默认值替换掉,换为{count:11},而子reducer2还是原始的默认state {count:0},因为preloadedState中并没有b这个key,所以从combineReducers原理中可以看到传入子reducer2中的state[key]是一个undefined。
<2> 无preloadedState:
通过<1>中可以看到,如果没有preloadedState,那么combineReducers()生成的那个大的reducer中自带的state的默认值空对象{}就会生效,继而在初始化时,依次在空对象中找相应的key,空对象肯定是没有这个key的,所以初始化时所有的子reducer都是会使用其state设置的那个默认值。
<3>preloadedState为空对象{},那么combineReducers()生成的那个大的reducer中自带的state的默认值空对象{}就会被preloadedState为空对象{}替换,继而在初始化时,依次在空对象中找相应的key,空对象肯定是没有这个key的,所以初始化时所有的子reducer都是会使用其state设置的那个默认值。<2>和<3>意思差不多。

https://www.cntofu.com/book/4/docs/recipes/reducers/InitializingState.md

你可能感兴趣的:(redux的createStore第二参数preloadedState(初始化state)是如何控制单一或通过combineReducer组合生成的reducer中手动加的state的默认值是否生效的)