在 createStore 底部执行了一次 type 为随机的派发,这时执行 reducer,返回结果就会赋给 currentState 完成初始化
变量
1 2 3 4 5 6
let currentReducer = reducer let currentState = preloadedState let currentListeners = newMap() let nextListeners = currentListeners let listenerIdCounter = 0 let isDispatching = false
currentReducer 就是我们传入 createStore 的 reducer
currentState 就是初始化的 state
currentListeners 是一个 map用来存放订阅事件
nextListeners 是 currentListeners 的副本
isDispatching 用来判断是否处于 dispatch
getState
1 2 3 4 5 6 7 8 9 10
functiongetState() { if (isDispatching) { thrownewError( 'You may not call store.getState() while the reducer is executing. ' + 'The reducer has already received the state as an argument. ' + 'Pass it down from the top reducer instead of reading it from the store.' ) } return currentState; }
functionsubscribe(listener: () => void) { // listener 必须是一个 function if (typeof listener !== 'function') { thrownewError( `Expected the listener to be a function. Instead, received: '${kindOf( listener )}'` ) } // 在 dispatch 时不可以订阅 if (isDispatching) { thrownewError( 'You may not call store.subscribe() while the reducer is executing. ' + 'If you would like to be notified after the store has been updated, subscribe from a ' + 'component and invoke store.getState() in the callback to access the latest state. ' + 'See https://redux.js.org/api/store#subscribelistener for more details.' ) }
let isSubscribed = true // 确保下次的监听队列是最新的 ensureCanMutateNextListeners() // 向 nextListeners 加入新的 listener const listenerId = listenerIdCounter++ nextListeners.set(listenerId, listener) // 退订 returnfunctionunsubscribe() { // 如果没订阅,直接返回 if (!isSubscribed) { return } // dispatch 中不能退订 if (isDispatching) { thrownewError( 'You may not unsubscribe from a store listener while the reducer is executing. ' + 'See https://redux.js.org/api/store#subscribelistener for more details.' ) }
functiondispatch(action) { // 首先判断 action 是否是一个纯对象 if (!isPlainObject(action)) { thrownewError( `Actions must be plain objects. Instead, the actual type was: '${kindOf( action )}'. You may need to add middleware to your store setup to handle dispatching other values, such as 'redux-thunk' to handle dispatching functions. See https://redux.js.org/tutorials/fundamentals/part-4-store#middleware and https://redux.js.org/tutorials/fundamentals/part-6-async-logic#using-the-redux-thunk-middleware for examples.` ) } // 判断 action 是否存在 type 属性 if (typeof action.type === 'undefined') { thrownewError( 'Actions may not have an undefined "type" property. You may have misspelled an action type string constant.' ) } // 判断 action 的 type 是否是一个 string if (typeof action.type !== 'string') { thrownewError( `Action "type" property must be a string. Instead, the actual type was: '${kindOf( action.type )}'. Value was: '${action.type}' (stringified)` ) } // 如果正处于 dispatch 状态,不可以再进行 dispatch 会抛出错误 if (isDispatching) { thrownewError('Reducers may not dispatch actions.') }
let proto = obj // 获取到 obj 原型链非 null 的顶层,赋值给 proto while (Object.getPrototypeOf(proto) !== null) { proto = Object.getPrototypeOf(proto) } // 判断 obj 的原型是否为 proto action。其实就是判断 obj 是否存在继承关系,存在则返回 false returnObject.getPrototypeOf(obj) === proto }
replaceReducer
1 2 3 4 5 6 7 8 9 10 11 12 13 14
functionreplaceReducer(nextReducer) { // 新的 reducer 必须是一个 function if (typeof nextReducer !== 'function') { thrownewError( `Expected the nextReducer to be a function. Instead, received: '${kindOf( nextReducer )}` ) } // 进行替换 currentReducer = nextReducer // 进行一次派发 dispatch({ type: ActionTypes.REPLACE }) }