首頁  >  文章  >  web前端  >  透過ES6寫法去對Redux部分源碼解讀

透過ES6寫法去對Redux部分源碼解讀

不言
不言原創
2018-07-07 11:12:511182瀏覽

這篇文章主要介紹了透過ES6寫法去對Redux部分源碼解讀,有著一定的參考價值,現在分享給大家,有需要的朋友可以參考一下

在Redux源碼中主要有四個檔案createStore,applyMiddleware,bindActionCreators,combineRedures

createStore.js

#export default function createStore(reducer,

export default function createStore(reducer,

export default function createStore(reducer,

export default function createStore(reducer,

export default preloadedState, enhancer),其中reducer函數是用來計算規則,preloadedState是初始狀態,enhancer(高階組合函數)是用來增強store對象,傳回增強後的store

# createStore將透過閉包的方式,封裝私有變量,該store中的state等狀態會被保存//傳回store 暴漏出的介面

return {
dispatch, //唯一一个可以改变 state 的哈按时
subscribe, //订阅一个状态改变后,要触发的监听函数
getState, // 获取 store 里的 state
replaceReducer, //Redux热加载的时候可以替换 Reducer
[$$observable]: observable //对象的私有属性,供内部使用
}
如果preloadedState 是function,而enhancer為null,那麼將兩者交換,enhancer必須是function

if (typeof preloadedState === 'function' && typeof enhancer === 'undefined') {
enhancer = preloadedState // 把 preloadedState 赋值给 enhancer
preloadedState = undefined // 把 preloadedState 赋值为 undefined
}

function subscribe(listener)主要透過觀察者模式傳回一個取消訂閱的函數,訂閱透過一個陣列佇列來完成,新增或取消監聽之前都會儲存一份訂閱快照

在function dispatch(action)中,

//標記dispatch 正在執行

##isDispatching = true

//執行目前Reducer 函數傳回新的state

currentState = currentReducer(currentState, action)

然後對所有的訂閱陣列佇列,進行遍歷

//所有的的监听函数赋值给 listeners
var listeners = currentListeners = nextListeners
 
//遍历所有的监听函数
for (var i = 0; i < listeners.length; i++) {
 
// 执行每一个监听函数
listeners[i]()

applyMiddleware

return一個函數,它可以接受createStore方法作為參數,給傳回的store的dispatch方法再進行一次包裝

return function (reducer, preloadedState, enhancer) {
var store = createStore(reducer, preloadedState, enhancer);
var _dispatch = store.dispatch; //获取dispatch
var chain = [];
 
var middlewareAPI = {
getState: store.getState,
dispatch: function dispatch(action) {
return _dispatch(action);
}
};
chain = middlewares.map(function (middleware) { //遍历middlewares绑定
return middleware(middlewareAPI);
});
_dispatch = compose.apply(undefined, chain)(store.dispatch);
 
return _extends({}, store, {
dispatch: _dispatch
});
};

bindActionCreators

將action和dispatch綁定:

bindActionCreators(actionCreators, dispatch)

// 判断 actionCreators 是一个函数
if (typeof actionCreators === 'function') {
// 调用 bindActionCreator , 返回包装后的 actionCreators , 包装后 actionCreators 可以直接 dispath
return bindActionCreator(actionCreators, dispatch);
}
如果是Object对象的话,遍历Object的key,获取Oobject每个key对应的value
// 获取 actionCreators 所有的 key
var keys = Object.keys(actionCreators);
// 用来保存新 转换后的 actionCreators
var boundActionCreators = {};
 
// 遍历 所有的 actionCreators keys
for (var i = 0; i < keys.length; i++) {
var key = keys[i];
// 获取当前的 actionCreator
var actionCreator = actionCreators[key];
// 当前的 actionCreator 是一个函数
if (typeof actionCreator === 'function') {
// 调用 bindActionCreator , 返回包装后的 actionCreators , 包装后 actionCreators 可以直接 dispath
boundActionCreators[key] = bindActionCreator(actionCreator, dispatch);
}
combineReducers

取得combineReduces傳進來的對象,取得物件的所有key集合finalReducerKeys。


取得state集合,遍歷reducers集合找到目前reducers中的state,然後和經過reducer後的獲取的新的state做對比,如果發生改變返回state
//循环遍历 finalReducerKeys ,执行所有的 reducer, 所以大家一定不要有相同的 action.type ,否则你的状态一定会混乱的
for (var i = 0; i < finalReducerKeys.length; i++) {
//获取当前的 key
var key = finalReducerKeys[i]
//获取当前 reducer
var reducer = finalReducers[key]
//获取当前 key 的 state
var previousStateForKey = state[key]
//执行 reducer ,获取 state
var nextStateForKey = reducer(previousStateForKey, action)
//判断执行完Reducer后, 返回回来的 nextStateForKey 是 undefined
if (typeof nextStateForKey === 'undefined') {
//得到 Undefined 状态的错误消息
var errorMessage = getUndefinedStateErrorMessage(key, action)
//抛出异常
throw new Error(errorMessage)
}
//赋值给 nextState
nextState[key] = nextStateForKey
//判断 state 是否经过 Reducer 改变了
hasChanged = hasChanged || nextStateForKey !== previousStateForKey
}
//返回state
return hasChanged ? nextState : state

以上就是本文的全部內容,希望對大家的學習有幫助,更多相關內容請關注PHP中文網!

相關推薦:
Javascript中的this物件

##########foreach, for in, for of 之間的異同#### ###########React-Reflux的基礎介紹#########

以上是透過ES6寫法去對Redux部分源碼解讀的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn