此篇文章可作為redux源碼導讀運用,只說清楚明了个中部份中心代碼,並進行了一些簡化處置懲罰
用法回憶
- 用createStore來建立store
- 建立Action
- 在Reducer中編寫純函數來處置懲罰Action
- 用Store.dispatch()經由過程Action和Reducer來操縱Store里的數據
- 用Store.subscribe()來監聽Store中的數據是不是發生了變化
- 用store.getState()來獵取Store中的state,並更新視圖
中心代碼
createStore(reducer, preloadedState, enhancer)
1.初始化數據
let currentReducer = reducer
let currentState = preloadedState //寄存state,preloadedState是傳入的默認值
let currentListeners = [] //寄存subscribe傳入的listener
let nextListeners = currentListeners
2.建立dispatch, subscribe, getState等要領
dispatch(action)
1.實行reducer
currentReducer(currentState, action)
2.實行listener
const listeners = (currentListeners = nextListeners)
for (let i = 0; i < listeners.length; i++) {
const listener = listeners[i]
listener()
}
subscribe(listener)
nextListeners.push(listener)
getState()
return currentState
applyMiddleware(…middlewares)
const applyMiddleware = (...middlewares) => createStore => (...args) => {
const 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)))
}
const store = createStore(...args)
let dispatch = () => {
throw new Error(
`Dispatching while constructing your middleware is not allowed. ` +
`Other middleware would not be applied to this dispatch.`
)
}
let chain = []
const middlewareAPI = {
getState: store.getState,
dispatch: (...args) => dispatch(...args)
}
chain = middlewares.map(middleware => middleware(middlewareAPI)) //*1 middlewareAPI是store
dispatch = compose(...chain)(store.dispatch) //*2 ...chain和store.dispatch是next
return { ...store, dispatch } //*3 實行dispatch傳入action
}
compose是函數式編程的用法用於簡化函數嵌套實行
我們來看看middleware是怎樣寫的
const logger = store => next => action => {
console.log('dispatching', action)
let result = next(action)
console.log('next state', store.getState())
return result
}
為何會變成 store => next => action => ?
- 第一個store是傳入的middlewareAPI
- 第二個next是經由過程compose合成…middleware和store.dispatch完成中間件級聯
- 第三個action是實行dispatch傳入的action
(見解釋)