本文将深入剖析 Redux 的源码,从入口函数开始一步步分析每个细节,帮助读者深入理解 Redux 并能够编写出更加高效的 Redux 应用。
入口函数
Redux 的入口函数如下:
-- -------------------- ---- ------- ------ ----------- ---- ---------------- ------ ------------------ ---- ----------------------- ------ --------------- ---- -------------------- ------ --------------- ---- -------------------- ------ ------- ---- ------------ ------ - ------------ ---------------- ------------------- ---------------- ------- --
通过 import 关键字引入 createStore、bindActionCreators、combineReducers、applyMiddleware 和 compose 函数,然后通过 export 关键字导出。
createStore 函数
createStore 函数是 Redux 最核心的部分,它的作用是产生一个全局唯一的 store,用于存储应用中所有状态。它的实现如下:
-- -------------------- ---- ------- ------ ------------- ---- ----------------------- ------ ------- ---- ------------------ -------- -------------------- --------------- --------- - -- ------- -------------- --- ---------- -- ------ -------- --- ------------ - -------- - --------------- -------------- - ---------- - -- ------- -------- --- ------------ - -- ------- -------- --- ----------- - ----- --- --------------- --- -------- -- -- - ------------ - ------ ------------------------------ ---------------- - -- ------- ------- --- ----------- - ----- --- --------------- --- ------- -- -- - ------------ - --- -------------- - -------- --- ------------ - --------------- --- ---------------- - --- --- ------------- - ----------------- --- ------------- - ------ -------- ------------------------------ - -- -------------- --- ----------------- - ------------- - ------------------------- - - -------- ---------- - -- --------------- - ----- --- ------ ---- --- --- ---- ---------------- ----- --- ------- -- ---------- - - ---- ------- --- ------- -------- --- ----- -- -- --------- - - ----- -- ---- ---- --- --- ------- ------- -- ------- -- ---- --- ------- -- - ------ ------------- - -------- ------------------- - -- ------- -------- --- ----------- - ----- --- --------------- --- -------- -- -- - ------------ - --- ------------ - ----- ------------------------------- ----------------------------- ------ -------- ------------- - -- --------------- - ------- - ------------ - ------ ------------------------------- ----- ----- - -------------------------------- --------------------------- --- ---------------- - ----- -- - -------- ---------------- - -- ------------------------ - ----- --- ------ -------- ---- -- ----- -------- - - ---- ------ ---------- --- ----- --------- -- - -- ------- ----------- --- ------------ - ----- --- ------ -------- --- --- ---- -- --------- ------ --------- - - ----- --- ---------- - ---------- -- - -- --------------- - ----- --- --------------- --- --- -------- ----------- - --- - ------------- - ----- ------------ - ---------------------------- -------- - ------- - ------------- - ------ - ----- --------- - ----------------- - --------------- --- ---- - - -- - - ----------------- ---- - ----- -------- - ------------- ----------- - ------ ------- - -------- --------------------------- - -- ------- ----------- --- ----------- - ----- --- --------------- --- ----------- -- -- - ------------ - -------------- - ------------ ---------- ----- -------------- --- - ---------- ----- -------------- --- ------ - --------- ---------- --------- -------------- -- -
我们来一步步分解这个函数。
- 入参
function createStore(reducer, preloadedState, enhancer) {
入参有三个:
- reducer:必选参数,reducer 函数,用于处理应用中所有的 action,返回新的全局 state;
- preloadedState:可选参数,初始化的 state,如果不传则为 undefined;
- enhancer:可选参数,一个增强器函数,用于增强 createStore 函数的功能。
- 处理 enhancer
-- -------------------- ---- ------- -- ------- -------------- --- ---------- -- ------ -------- --- ------------ - -------- - --------------- -------------- - ---------- - -- ------- -------- --- ------------ - -- ------- -------- --- ----------- - ----- --- --------------- --- -------- -- -- - ------------ - ------ ------------------------------ ---------------- -
如果 preloadedState 是函数,并且 enhancer 未定义,则把 preloadedState 赋值给 enhancer,preloadedState 赋值为 undefined。
如果 enhancer 存在,则判断 enhancer 是否是一个函数,如果不是,则抛出错误。如果 enhancer 是一个函数,则把 createStore 传入 enhancer,enhancer 返回的是一个增强版的 createStore 函数。
- 处理 reducer
-- -------------------- ---- ------- -- ------- ------- --- ----------- - ----- --- --------------- --- ------- -- -- - ------------ - --- -------------- - -------- --- ------------ - --------------- --- ---------------- - --- --- ------------- - ----------------- --- ------------- - ------
如果 reducer 不是一个函数,则抛出异常。
currentReducer 存储目前的 reducer;currentState 存储目前的 state;currentListeners 存储当前注册的所有 listener;nextListeners 是 currentListeners 的引用,确保 dispatch 时未注册的 listener 不会遗漏。
- 辅助函数
-- -------------------- ---- ------- -------- ------------------------------ - -- -------------- --- ----------------- - ------------- - ------------------------- - - -------- ---------- - -- --------------- - ----- --- ------ ---- --- --- ---- ---------------- ----- --- ------- -- ---------- - - ---- ------- --- ------- -------- --- ----- -- -- --------- - - ----- -- ---- ---- --- --- ------- ------- -- ------- -- ---- --- ------- -- - ------ ------------- - -------- ------------------- - -- ------- -------- --- ----------- - ----- --- --------------- --- -------- -- -- - ------------ - --- ------------ - ----- ------------------------------- ----------------------------- ------ -------- ------------- - -- --------------- - ------- - ------------ - ------ ------------------------------- ----- ----- - -------------------------------- --------------------------- --- ---------------- - ----- -- - -------- ---------------- - -- ------------------------ - ----- --- ------ -------- ---- -- ----- -------- - - ---- ------ ---------- --- ----- --------- -- - -- ------- ----------- --- ------------ - ----- --- ------ -------- --- --- ---- -- --------- ------ --------- - - ----- --- ---------- - ---------- -- - -- --------------- - ----- --- --------------- --- --- -------- ----------- - --- - ------------- - ----- ------------ - ---------------------------- -------- - ------- - ------------- - ------ - ----- --------- - ----------------- - --------------- --- ---- - - -- - - ----------------- ---- - ----- -------- - ------------- ----------- - ------ ------- - -------- --------------------------- - -- ------- ----------- --- ----------- - ----- --- --------------- --- ----------- -- -- - ------------ - -------------- - ------------ ---------- ----- -------------- --- -
- ensureCanMutateNextListeners:确保 nextListeners 存在,若不存在则将 nextListeners 的引用赋值为 currentListeners 的拷贝。
- getState:获取当前的 state。
- subscribe:注册 listener,返回一个函数,用于取消注册。
- dispatch:根据 action 更新 state 并遍历所有注册的 listener,返回 action。
- replaceReducer:用于动态替换 reducer,替换后会重新执行一次 INITIAL 操作。
值得注意的是 getState 和 dispatch 这两个函数中通过 isDispatching 变量避免了 reducer 函数的递归调用。
- 初始化
dispatch({ type: '@@redux/INIT' });
每个 store 一旦初始化完毕,就会自动 dispatch 一个带有 type 属性的 action,type 属性为 "@@redux/INIT"。
- 返回值
return { dispatch, subscribe, getState, replaceReducer };
返回一个对象,包含 dispatch、subscribe、getState 和 replaceReducer 属性。
上面的函数使 createStore 成为一个功能强大的函数,能够接收 reducer、preloadedState 和 enhancer 参数,返回一个包含更改应用状态的事件驱动对象。
总结
本文对 Redux 的入口函数和 createStore 进行了详细的分析,其中包括了函数的实现方式和具体细节。最后还给出了合适的示例代码,帮助读者深入理解如何使用 Redux,并能够更好地与其它库结合使用。对于前端开发者来说,深入了解 Redux 的内部实现,将有助于提高应用程序的性能,增强代码质量,提升开发效率。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/6651ee49d3423812e464c6a5