準(zhǔn)備工作
redux 工作流程
- 首先由用戶發(fā)出action store.dispatch(action)
- store 自動調(diào)用reducer 并傳入兩個參數(shù)當(dāng)前 State 和收到的 Action,reducer 會返回新的state
- state有變化 store 會調(diào)用監(jiān)聽函數(shù)
4.視圖需設(shè)置監(jiān)聽函數(shù)store.subscribe(listener)
5.listener可以通過store.getState()得到當(dāng)前狀態(tài)
總結(jié)
- createStore 創(chuàng)建store
- reducer 初始化袍镀、修改狀態(tài)函數(shù)(用戶自己定義傳入)
- getState 獲取狀態(tài)值
- dispatch 提交更新
- subscribe 變更訂閱
createStore
以下為精簡部分代碼,感興趣直接去github 上下載源碼
export default function createStore<
S,
A extends Action,
Ext = {},
StateExt = never
>(
reducer: Reducer<S, A>,
enhancer?: StoreEnhancer<Ext, StateExt>
// createStore 入?yún)⒂袃蓚€ 一個reducer 一個enhancer 用來使用中間件增強(qiáng)函數(shù)
):
let currentState = preloadedState as S //內(nèi)部的state存璃,用來存儲數(shù)據(jù)
let currentListeners: (() => void)[] | null = [] // 用來存放訂閱回調(diào)的數(shù)組
let nextListeners = currentListeners
if (typeof enhancer !== 'undefined') { // 如果 enhancer 不為空 則返回一個增強(qiáng)的 createStore
return enhancer(createStore)(
reducer,
preloadedState as PreloadedState<S>
) as Store<ExtendState<S, StateExt>, A, StateExt, Ext> & Ext
}
function getState(): S {
// 返回 當(dāng)前state 外部可以通過 store.getState()獲取
return currentState as S
}
function subscribe(listener: () => void){
nextListeners.push(listener) // 將callback 放入 監(jiān)聽數(shù)組,當(dāng)state 發(fā)生改變的時候會遍歷調(diào)用
return function unsubscribe() { // 同時返回一個取消訂閱的函數(shù)
const index = nextListeners.indexOf(listener)
nextListeners.splice(index, 1)
currentListeners = null
}
}
function dispatch(action: A) {
currentState = currentReducer(currentState, action) // 此處調(diào)用reducer 將state 傳入
// 調(diào)用綁定監(jiān)聽回調(diào)
const listeners = (currentListeners = nextListeners)
for (let i = 0; i < listeners.length; i++) {
const listener = listeners[i]
listener()
}
return action
}
最后返回
const store = {
dispatch: dispatch as Dispatch<A>,
subscribe,
getState,
replaceReducer,
[$$observable]: observable
} as unknown as Store<ExtendState<S, StateExt>, A, StateExt, Ext> & Ext
return store
applyMiddleware
const store = createStore(reducer, preloadedState)
const middlewareAPI: MiddlewareAPI = {
getState: store.getState,
dispatch: (action, ...args) => dispatch(action, ...args)
} // 將 控制權(quán)包裝一下
const chain = middlewares.map(middleware => middleware(middlewareAPI)) // 將控制權(quán)傳給中間件
dispatch = compose<typeof dispatch>(...chain)(store.dispatch) // 通過 compose 函數(shù) 將中間件串聯(lián)起來
return {
...store,
dispatch // 返回包裝后的dispatch
}
compose 函數(shù) 用來組合各種中間件
function compose(...funs){
if(funs.length === 0){
return (arg)=>arg
}
if(funs.length === 1){
return funs[0]
}
return funs.reduce((a,b)=>(...args)=>a(b(...args)))
}
未完 待續(xù)