首先,个人比较少些文章,可能文笔不太好,请勿喷,第二,本文仅限于个人理解,如果异议,欢迎一同探讨QQ:251801008
接下来还会写其他相关的文章
首先我们可以看到redux源码目录下的源码主要只有6个文件
在utils包下面的是一个工具类,用来抛出错误警告
我们主要关注的是applyMiddleware,bindActinCreators,combineReducers,compose,createStore,index这几个文件
我们先从index入口文件开始,这个入口文件比较简单,就是将其他的5个JS文件进行导出。
我们一般使用redux是怎么使用的呢?
eg:
const store = createStore(
combineReducers({ ...reducers }),
initialState,
enhancer
);
我们一般使用createStore来进行创建store。
现在我们来看看createStore到底做了什么事情。
首先我们看看这函数的入参,入参有3个 reducer, preloadedState, enhancer。
我们先来讲讲这3个参数分别是干什么用的
reducer:这个是redux流程中我们写的处理action的reducer的处理函数
preloadedState:这个就是初始化的state
enhancer:这个是createStore的增强器。
上面的参数接着往下走
if (typeof preloadedState === 'function' && typeof enhancer === 'undefined') {
enhancer = preloadedState
preloadedState = undefined
}
if (typeof enhancer !== 'undefined') {
if (typeof enhancer !== 'function') {
throw new Error('Expected the enhancer to be a function.')
}
return enhancer(createStore)(reducer, preloadedState)
}
if (typeof reducer !== 'function') {
throw new Error('Expected the reducer to be a function.')
}
这一段代码是对于入参的类型判断,这里有一个地方需要注意,如果存在enhancer,那么将执行enhancer,后面代码将不会执行
let currentReducer = reducer
let currentState = preloadedState
let currentListeners = []
let nextListeners = currentListeners
let isDispatching = false
这里是对于入参的缓存,和定义一些局部变量。也比较简单
function ensureCanMutateNextListeners() {
if (nextListeners === currentListeners) {
nextListeners = currentListeners.slice()
}
}
这个函数主要是确保nextListernners 和 currentListnerers 不是同一个内存地址,但是数据是一样的。
function getState() {
return currentState
}
这个获取state状态树
function subscribe(listener) {
if (typeof listener !== 'function') {
throw new Error('Expected listener to be a function.')
}
let isSubscribed = true
ensureCanMutateNextListeners()
nextListeners.push(listener)
return function unsubscribe() {
if (!isSubscribed) {
return
}
isSubscribed = false
ensureCanMutateNextListeners()
const index = nextListeners.indexOf(listener)
nextListeners.splice(index, 1)
}
}
subscribe方法主要是用来添加一个监听。
这里会将你传入的函数push到nextListeners,并且返回一个unsubScribe函数来进行监听的移除。
不知道什么原因贴图不显示了。。。就用文本了
function dispatch(action) {
if (!isPlainObject(action)) { // 判断actions是不是个对象
throw new Error(
'Actions must be plain objects. ' +
'Use custom middleware for async actions.'
)
}
if (typeof action.type === 'undefined') { // 判断action中是否包含type
throw new Error(
'Actions may not have an undefined "type" property. ' +
'Have you misspelled a constant?'
)
}
if (isDispatching) { // isDispatching在开始的时候有进行定义, isDispatching = false
throw new Error('Reducers may not dispatch actions.')
}
try {
isDispatching = true
currentState = currentReducer(currentState, action) // 执行reducer
} finally {
isDispatching = false
}
const listeners = currentListeners = nextListeners // 将nextListeners赋值给currentListeners,listeners
for (let i = 0; i < listeners.length; i++) { // 循环遍历listeners,
const listener = listeners[i] // 取出数组对应的监听
listener() // 执行监听
}
return action // 返回action
}
function replaceReducer(nextReducer) { // 用来替换reducer
if (typeof nextReducer !== 'function') {
throw new Error('Expected the nextReducer to be a function.')
}
currentReducer = nextReducer
dispatch({ type: ActionTypes.INIT }) // 重新构建初始化的state树
}
observable 这个是redux 一个观察者的模式
function observable() {
const outerSubscribe = subscribe
return {
/**
* The minimal observable subscription method.
* @param {Object} observer Any object that can be used as an observer.
* The observer object should have a `next` method.
* @returns {subscription} 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) {
if (typeof observer !== 'object') {
throw new TypeError('Expected the observer to be an object.')
}
function observeState() {
if (observer.next) {
observer.next(getState())
}
}
observeState()
const unsubscribe = outerSubscribe(observeState)
return { unsubscribe }
},
[$$observable]() {
return this
}
}
}
return {
dispatch,
subscribe,
getState,
replaceReducer,
[$$observable]: observable
}
在最后将需要用到的API返回。