读redux源码
2021-07-26 本文已影响0人
南枫小谨
准备工作
redux 工作流程
- 首先由用户发出action store.dispatch(action)
- store 自动调用reducer 并传入两个参数当前 State 和收到的 Action,reducer 会返回新的state
- state有变化 store 会调用监听函数
4.视图需设置监听函数store.subscribe(listener)
5.listener可以通过store.getState()得到当前状态
总结
- createStore 创建store
- reducer 初始化、修改状态函数(用户自己定义传入)
- getState 获取状态值
- dispatch 提交更新
- subscribe 变更订阅
createStore
以下为精简部分代码,感兴趣直接去github 上下载源码
export default function createStore<
S,
A extends Action,
Ext = {},
StateExt = never
>(
reducer: Reducer<S, A>,
enhancer?: StoreEnhancer<Ext, StateExt>
// createStore 入参有两个 一个reducer 一个enhancer 用来使用中间件增强函数
):
let currentState = preloadedState as S //内部的state,用来存储数据
let currentListeners: (() => void)[] | null = [] // 用来存放订阅回调的数组
let nextListeners = currentListeners
if (typeof enhancer !== 'undefined') { // 如果 enhancer 不为空 则返回一个增强的 createStore
return enhancer(createStore)(
reducer,
preloadedState as PreloadedState<S>
) as Store<ExtendState<S, StateExt>, A, StateExt, Ext> & Ext
}
function getState(): S {
// 返回 当前state 外部可以通过 store.getState()获取
return currentState as S
}
function subscribe(listener: () => void){
nextListeners.push(listener) // 将callback 放入 监听数组,当state 发生改变的时候会遍历调用
return function unsubscribe() { // 同时返回一个取消订阅的函数
const index = nextListeners.indexOf(listener)
nextListeners.splice(index, 1)
currentListeners = null
}
}
function dispatch(action: A) {
currentState = currentReducer(currentState, action) // 此处调用reducer 将state 传入
// 调用绑定监听回调
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)
} // 将 控制权包装一下
const chain = middlewares.map(middleware => middleware(middlewareAPI)) // 将控制权传给中间件
dispatch = compose<typeof dispatch>(...chain)(store.dispatch) // 通过 compose 函数 将中间件串联起来
return {
...store,
dispatch // 返回包装后的dispatch
}
compose 函数 用来组合各种中间件
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)))
}
未完 待续