【Redux】源码简读
笔记系列,逻辑不太清晰。主要是用大白话,记录一下两类 state 的区别(之前自己有点小迷糊)
想了想,还是发布吧。
redux 源码很少,也好读。建议直接读源码。
有问题可以留言讨论~
一、【redux系列】createStore、combineReducers、applyMiddleware
// 以添加 sagaMiddleware 为例
const sagaMiddleware = createSagaMiddleware()
middleWares.push(sagaMiddleware)
const store = createStore(reducer, applyMiddleware(...middleWares))
【能力汇总】
(1)createStore 创建 store 对象
(2)combineReducers 收集所有 reducer
(3)applyMiddleware 逐个执行(按数组倒序执行)每个 middleware,扩展 dispatch
其中,reducer 是一个方法。
单个的 reducer 方法 或 combineReducers 返回的 combination 方法。
combination 方法会逐个执行每一个 combine 的 reducer,遍历执行,不中断。
每一次调用 dispatch,dispatch 方法内部,都会执行:
// 初始 currentState 传入的是 undefined
currentState = currentReducer(currentState, action)
调用 currentReducer,更新 currentState。
如果是 combineReducers 情况,这个 currentReducer,就是 combineReducers 返回的 combination 方法。(会遍历执行每一个 reducer,不中断)
如果是单个 reducer 的情况,这个 currentReducer 就是执行 reducer 方法。
这里, currentState 变量,是一个全局变量。只有 dispatch 方法会更新它。
如果是 combineReducers 情况,currentState 对象的 key,就是传入 combineReducers 的那个对象的 key,也就是每个 reducer 的名称,对应的 value 则是执行相应 reducer 返回的那个 state 对象。
如果是单个 reducer 的情况,currentState 就是 reducer 返回的 state 对象。
createStore 的过程中,会默认 dispatch({ type: ActionTypes.INIT }),直接触发一次 reducer 的执行。
如果开发者设置了 initialState,则 currentState 会获得这个初始值。
store 得到的,是一个对象:
{
dispatch,
subscribe,
getState, // store.getState() 拿到 currentState
replaceReducer,
[$$observable]: observable
}
二、【react-redux系列】connect、mapStateToProps、mapDispatchToProps
// 把 state,映射为当前组件的 props
const mapStateToProps = (state: any, ownProps: any) => {}
// 把 dispatch,映射为当前组件的 props
const mapDispatchToProps = (dispatch: any, ownProps: any) => {}
【注】
mapStateToProps 的第一个参数,拿到的是 currentState。
以 combineReducers 情况为例:
export default combineReducers({
cityList: cityListReducer,
actList: actListReducer,
signList: signListReducer
})
则:
const mapStateToProps = (state: any, ownProps: any) => {
// { cityList: {page: 1, data: [], total: 10}, actList: {page: 1, data: [], total: 10}, signList: {page: 1, data: [], total: 10} }
console.log('state:', state)
}
这里的 state,就是 createStore 时创建的 currentState。
它的每一个 value,对应执行每个 reducer 后,返回的 state。
【特别注意】
*** mapStateToProps 的第一个参数 state,和每个 reducer 拿到的第一个参数 state,不是一个state !! ***
可以认为:
mapStateToProps 的第一个参数 state, 是大的 state。
它的 key,是传入 combineReducers 的每一个 reducer 的名字,value 是执行这个 reducer 返回的 state。
reducer 的第一个参数 state,则是小的 state,它是每个 reducer 对应的 state。
【写个直观的例子,来说明这个关系】
1、执行 combineReducers:
combineReducers({
actList: actListReducer,
userList: userListReducer
})
2、执行 createStore:
默认执行一次 dispatch, dispatch({ type: ActionTypes.INIT }),触发 reducer 遍历。
执行每一个 reducer,返回每个 reducer 的默认 state(initialState。如果没有设置,就会返回 {} )
3、假设初始化后,得到的 currentState 如下:
currentState = {
actList: { page:1, total: 10, data: [ ] },
userList: { page:2, total: 20, data: [ ] }
}
store.getState() 和 mapStateToProps 的第一个参数 state,都等于 currentState。
4、假设 actListReducer 逻辑如下:
export default (state = {}, action) => {
switch (action.type) {
case ACTLIST:
return {
...state,
...action.payload,
}
default:
return state
}
}
请注意,这里的 state,不是 currentState !!
而是,currentState.actList,也就是说,这个 state === { page:1, total: 10, data: [ ] }。
同样,这里返回的 state,修改的也只是 currentState.actList 的值。
currentState 是大的 state,reducer 方法接收的 state,是小的 state。