// 获取当前的state functiongetState(): S{ // 如果正在dispatch 就报错,因为要获取最新的state, dispatch很有可能会改变state 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.' ) }
functionsubscribe(listener: () => void) { // listener必须为函数,因为要以回调函数的方式来触发。 if (typeof listener !== 'function') { thrownewError('Expected the listener to be a function.') }
// 如果正在dispatch中则抛错,和getState同理 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.' ) }
// 返回一个取消订阅的方法 returnfunctionunsubscribe() { // 如果没有被订阅, 直接shut down 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.' ) }
// 修改store的唯一方法 functiondispatch(action: A) { // action必须是一个对象 if (!isPlainObject(action)) { thrownewError( 'Actions must be plain objects. ' + 'Use custom middleware for async actions.' ) }
// action必须拥有一个type if (typeof action.type === 'undefined') { thrownewError( 'Actions may not have an undefined "type" property. ' + 'Have you misspelled a constant?' ) }
// 如果正在dispatching,那么不执行dispatch操作。 if (isDispatching) { thrownewError('Reducers may not dispatch actions.') }
// 这个其实很少用到, 官方的介绍是主要是用于动态替换reducer的时候会用到 functionreplaceReducer<NewState, NewActionsextendsA>( nextReducer: Reducer<NewState, NewActions> ): Store<ExtendState<NewState, StateExt>, NewActions, StateExt, Ext> & Ext{ if (typeof nextReducer !== 'function') { thrownewError('Expected the nextReducer to be a function.') }
// 修改reducer // 当前的currentReducer更新为参数nextReducer // TODO: do this more elegantly ;((currentReducer as unknown) as Reducer< NewState, NewActions >) = nextReducer
// This action has a similar effect to ActionTypes.INIT. // Any reducers that existed in both the new and old rootReducer // will receive the previous state. This effectively populates // the new state tree with any relevant data from the old one. // 和INIT的dispatch相同,发送一个dispatch初始化state,表明一下是REPLACE // 自己👀看一下utils方法的ActionTypes, 随性的随机数 dispatch({ type: ActionTypes.REPLACE } as A) // change the type of the store by casting it to the new store return (store as unknown) as Store< ExtendState<NewState, StateExt>, NewActions, StateExt, Ext > & Ext }
/** * These are private action types reserved by Redux. * For any unknown actions, you must return the current state. * If the current state is undefined, you must return the initial state. * Do not reference these action types directly in your code. */
// 查询之后,也没发现有什么特别的用处...暂时跳过,如果有帅哥看到的话可以不吝赐教 functionobservable() { const outerSubscribe = subscribe return { /** The minimal observable subscription method. @param observer Any object that can be used as an observer. The observer object should have a `next` method. @returns An object with an `unsubscribe` method that can be used to unsubscribe the observable from the store, and prevent further emission of values from the observable. */ subscribe(observer: unknown) { if (typeof observer !== 'object' || observer === null) { thrownewTypeError('Expected the observer to be an object.') }
//获取观察着的状态 functionobserveState() { const observerAsObserver = observer as Observer<S> if (observerAsObserver.next) { observerAsObserver.next(getState()) } }
exportdefaultfunctionapplyMiddleware( ...middlewares: Middleware[] ): StoreEnhancer<any> { return(createStore: StoreEnhancerStoreCreator) =><S,AextendsAnyAction>( reducer: Reducer<S, A>, preloadedState?: PreloadedState<S> ) => { const store = createStore(reducer, preloadedState) let dispatch: Dispatch = () => { throw new Error( 'Dispatching while constructing your middleware is not allowed. ' + 'Other middleware would not be applied to this dispatch.' ) }
exportdefaultfunctioncompose(...funcs: Function[]) { if (funcs.length === 0) { // infer the argument type so it is usable in inference down the line return<T>(arg: T) => arg }
if (funcs.length === 1) { return funcs[0] }
return funcs.reduce((a, b) => (...args: any) => a(b(...args))) }
// This is used to make sure we don't warn about the same // keys multiple times. // 意想不到的key, 先往下看看 let unexpectedKeyCache: { [key: string]: true } // production环境为{} if (process.env.NODE_ENV !== 'production') { unexpectedKeyCache = {} }
let shapeAssertionError: Error try { // 看这个function assertReducerShape(finalReducers) } catch (e) { shapeAssertionError = e }
functionassertReducerShape(reducers) { Object.keys(reducers).forEach(key => { const reducer = reducers[key] // reducer返回值 const initialState = reducer(undefined, { type: ActionTypes.INIT }) // undefined throw Error if (typeof initialState === 'undefined') { thrownewError( `Reducer "${key}" returned undefined during initialization. ` + `If the state passed to the reducer is undefined, you must ` + `explicitly return the initial state. The initial state may ` + `not be undefined. If you don't want to set a value for this reducer, ` + `you can use null instead of undefined.` ) }
// 很明显assertReducerShape是用于reducer的规范 // 回到combineReducers if ( typeof reducer(undefined, { type: ActionTypes.PROBE_UNKNOWN_ACTION() }) === 'undefined' ) { thrownewError( `Reducer "${key}" returned undefined when probed with a random type. ` + `Don't try to handle ${ ActionTypes.INIT } or other actions in "redux/*" ` + `namespace. They are considered private. Instead, you must return the ` + `current state for any unknown actions, unless it is undefined, ` + `in which case you must return the initial state, regardless of the ` + `action type. The initial state may not be undefined, but can be null.` ) } }) }