You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
if(typeofpreloadedState==='function'&&typeofenhancer==='undefined'){enhancer=preloadedStatepreloadedState=undefined}if(typeofenhancer!=='undefined'){if(typeofenhancer!=='function'){thrownewError('Expected the enhancer to be a function.')}returnenhancer(createStore)(reducer,preloadedState)}
functionsubscribe(listener){if(typeoflistener!=='function'){thrownewError('Expected listener to be a function.')}letisSubscribed=trueensureCanMutateNextListeners()nextListeners.push(listener)returnfunctionunsubscribe(){if(!isSubscribed){return}isSubscribed=falseensureCanMutateNextListeners()constindex=nextListeners.indexOf(listener)nextListeners.splice(index,1)}}
if(isDispatching){thrownewError('Reducers may not dispatch actions.')}try{isDispatching=truecurrentState=currentReducer(currentState,action)}finally{isDispatching=false}constlisteners=currentListeners=nextListenersfor(leti=0;i<listeners.length;i++){constlistener=listeners[i]listener()}
redux虽然强大,但是它的源码确实很简单
createStore
createStore返回的是一个对象,并且这个对象有如下成员函数
dispatch,subscribe,getState,replaceReducer
和observable
下面看它的核心源码(已经去掉一些对参数的判断):
这一段是通过传入的参数类型来做判断的如果只传入两个参数,并且第二个参数是函数而不是对象的时候,此时直接进行替换赋值。并且当检测到第三个参数
enhancer
不为空并且符合规范的时候,直接执行enhancer(createStore)(reducer, preloadedState)
这一段其实是为之后的中间件进行服务的
然后是定义了一系列变量:
currentState,currentListener,nextListener
等。然后就开始依次实现store
暴露的几个函数getState函数很简单,只是返回
currentState
而已subscribe函数的实现是通过
nextListener
数组来实现对当前listeners
来进行增删,之所有需要一个currentListener
又需要一个nextListener
,是因为如果直接在currentListener
上进行修改,会导致由于数组是复杂类型,一旦进行更改会使整个数组发生改变。上面是
dispatch
的核心源码,去掉了一些类型检测,这个函数主要是通过设置了一个isDispatching
标志位,来判断传入的action
是否已经被监听过,否则则直接调用reducer
函数,并且将listener
数组都执行一遍再继续往下看,
replaceReducer
也很简单,略过combineReducers
这部分的代码很长,但是大部分都是在对参数做一些校验处理,核心源码是下面几行
主要的过程如下:
reducer
是否是合法的,然后将合法的reducer
放进finalReducer
中,并获取对应的key
值reducer
获取对应key
值的state
state
通过上面的实现,那么下面两种写法也是等价的
bindActionCreators
这个函数的作用,主要是弱化了
store.dispatch
的作用,直接在bindActionCreators
中进行封装了,源码如下:actionCreators
这个参数是function
还是一系列function
数组function
,那就直接执行bindActionCreator
,可以看到bindActionCreator
中实现了dispatch
的功能applyMiddleware
这是唯一一个很绕的API,虽然代码很简洁,下面对它进行分析:
createStore
来生成一个store
,并且获取到dispatch
,定义了一个空数组chain
,store
和dispatch
作为参数传入middleware
中,先来看看中间件的统一格式:上面这个格式是采用了ES6的语法格式,解析应该是下面这样:
middleware
经过处理后push
到chain
数组compose
对chain
数组进行处理先来看看
compose
的实现源码:compose底层调用的是
Array.prototype.reduceRight
举例:
Dispatch = compose([fn1,fn2,fn3])(store.dispatch)
会被解析成如下所示:dispatch = f1(f2(f3(store.dispatch))
,也就是f3的返回值作为f2的参数,f2返回值作为f1的参数compose
处理后返回return next(action)
其实是如下:
这个也是包装后的
store.dispatch
,与原先的store.dispatch
不同,通过这种方式一直进行传递至此,完结
The text was updated successfully, but these errors were encountered: