输出:redux
{
dispatch,
subscribe,
getState,
replaceReducer,
[$$observable]: observable
}
复制代码
这些函数会调用到闭包里面的一些变量,如currentState, currentReducer, currentListeners。api
做用:将action和state传入reducer并修改对应的state,并执行listeners数组里面的全部listener 核心就是这句数组
currentState = currentReducer(currentState, action)
复制代码
做用:将一堆reducer存在闭包里面,最终返回一个总的reducer
输入:一个对象,对象中每一个属性对应一个reducerbash
{
task: (state, action) => {
switch (action.type) {
case 'CHANGE_FILTER_STATUS':
state.filterStatus = action.data
return state
default:
return state;
}
}
}
复制代码
核心代码:闭包
// 将reducer存到闭包中
const finalReducers = {}
for (let i = 0; i < reducerKeys.length; i++) {
const key = reducerKeys[i]
if (process.env.NODE_ENV !== 'production') {
if (typeof reducers[key] === 'undefined') {
warning(`No reducer provided for key "${key}"`)
}
}
if (typeof reducers[key] === 'function') {
finalReducers[key] = reducers[key]
}
}
// 输出:一个总的recuder函数,做用为遍历全部的reducer,返回一个state
return function combination(state = {}, action) {
let hasChanged = false
const nextState = {}
for (let i = 0; i < finalReducerKeys.length; i++) {
const key = finalReducerKeys[i]
const reducer = finalReducers[key]
const previousStateForKey = state[key]
const nextStateForKey = reducer(previousStateForKey, action)
if (typeof nextStateForKey === 'undefined') {
const errorMessage = getUndefinedStateErrorMessage(key, action)
throw new Error(errorMessage)
}
nextState[key] = nextStateForKey
hasChanged = hasChanged || nextStateForKey !== previousStateForKey
}
return hasChanged ? nextState : state
}
复制代码
核心代码:app
const middlewareAPI = {
getState: store.getState,
dispatch: (...args) => dispatch(...args)
}
const chain = middlewares.map(middleware => middleware(middlewareAPI))
dispatch = compose(...chain)(store.dispatch)
复制代码
其中compose其实就是使用array.reduce从右到左执行函数
compose核心代码:ide
return funcs.reduce((a, b) => (...args) => a(b(...args)))
复制代码
每次添加listener时都先深复制复制一份以前的listener
返回一个unsubscribe函数函数
let isSubscribed = true
ensureCanMutateNextListeners()
nextListeners.push(listener)
return function unsubscribe() {
if (!isSubscribed) {
return
}
if (isDispatching) {
throw new Error(
'You may not unsubscribe from a store listener while the reducer is executing. ' +
'See https://redux.js.org/api-reference/store#subscribe(listener) for more details.'
)
}
isSubscribed = false
ensureCanMutateNextListeners()
const index = nextListeners.indexOf(listener)
nextListeners.splice(index, 1)
}
复制代码
用array.slice()方法来深复制ui
function ensureCanMutateNextListeners() {
if (nextListeners === currentListeners) {
nextListeners = currentListeners.slice()
}
}
复制代码
经过分析redux的源码,首先咱们能够更好的理解咱们使用redux的时候,里面具体发生了什么事情,其次是能够更清楚地看到各类redux的插件是如何加入到redux里面的,对于咱们之后使用redux或者redux的插件会有帮助。
另外一方面,从代码的组织上来看,能够看到了里面有不少闭包的使用,还有各类各样的错误处理,以及简洁的语法,对于自身代码质量的提升也有必定的影响。spa