Redux 是前端开发中常用的状态管理库,其简单易用的 API 和灵活的架构让许多前端开发者爱不释手。不过,除了使用外,我们还需要了解其源码实现,来更好地理解其设计思路和背后的原理。本文将从源码角度对 Redux 进行解读。
createStore
createStore
是 Redux 的一个核心函数,用于创建一个状态容器。下面是其源码:
-- -------------------- ---- ------- ------ ------- -------- -------------------- --------------- --------- - -- ------- -------------- --- ---------- -- ------ -------- --- ------------ - -------- - -------------- -------------- - --------- - -- ------- -------- --- ------------ - -- ------- -------- --- ----------- - ----- --- --------------- --- -------- -- -- - ----------- - ------ ------------------------------ --------------- - -- ------- ------- --- ----------- - ----- --- --------------- --- ------- -- -- - ----------- - --- -------------- - ------- --- ------------ - -------------- --- ---------------- - -- --- ------------- - ---------------- --- ------------- - ----- -------- ------------------------------ - -- -------------- --- ----------------- - ------------- - ------------------------ - - -------- ---------- - -- --------------- - ----- --- ------ ---- --- --- ---- ---------- ----- --- ------- -- ---------- - - --- --- ---- -- ---- --- ------- ------ --- ---- -- ---- - ------ -------- -- ------------- - - --- ---------- ------- --- ------- ------ ---- -- --------- ------- ----- ----- -- - - -- ----------- ----- ------- -------- --- --- ----- ---- --- ------- -- -------- -------- - - ------ ------------ - -------- ------------------- - -- ------- -------- --- ----------- - ----- --- --------------- -------- -- -- - ----------- - --- ------------ - ---- ------------------------------ ---------------------------- ------ -------- ------------- - -- --------------- - ------ - ------------ - ----- ------------------------------ ----- ----- - ------------------------------- --------------------------- -- - - -------- ---------------- - -- ------------------------ - ----- --- ------ -------- ---- -- ----- -------- - - ---- ------ ---------- --- ----- --------- - - -- ------- ----------- --- ------------ - ----- --- ------ -------- --- --- ---- -- --------- ------ --------- - - ----- --- ---------- - ---------- - - -- --------------- - ----- --- --------------- --- --- -------- ---------- - --- - ------------- - ---- ------------ - ---------------------------- ------- - ------- - ------------- - ----- - ----- --------- - ----------------- - -------------- --- ---- - - -- - - ----------------- ---- - ----- -------- - ------------ ---------- - ------ ------ - -------- ---------------- - ----- --- ----------- ------ --- ---- -------- --- --- ------- ------ ------------------------------------------------------------------- - ---------- ----- ---------------- -- ------ - --------- ---------- --------- --------------- - -展开代码
我们可以看到,createStore
整个函数有点长,但主要分为以下几个部分:
- 确定 preloadedState 和 enhancer 参数;
- 如果 enhancer 存在,则使用 enhancer 对 createStore 函数重新包装;
- 初始化 currentReducer、currentState、currentListeners 等各种状态;
- 定义 getState、subscribe、dispatch、replaceReducer 四个函数。
其中,getState
函数用于获取当前状态,subscribe
用于订阅状态变化,dispatch
用于发送一个 Action 并触发状态变化,replaceReducer
用于替换当前的 reducer。
combineReducers
combineReducers
用于将多个 Reducer 合并成一个。其主要实现思路是对每个 Reducer 接收到的 state 和 action 进行处理,并返回一个新的 state,最终将所有 Reducer 的 state 合并成一个对象。以下是其源码:
-- -------------------- ---- ------- ------ ------- -------- ------------------------- - ----- ----------- - --------------------- ----- ------------- - -- --- ---- - - -- - - ------------------- ---- - ----- --- - -------------- -- ------- ------------- --- ----------- - ------------------ - ------------- - - ----- ---------------- - -------------------------- ------ -------- ----------------- - --- ------- - --- ---------- - ----- ----- --------- - -- --- ---- - - -- - - ------------------------ ---- - ----- --- - ------------------- ----- ------- - ------------------ ----- ------------------- - ---------- ----- --------------- - ---------------------------- ------- -------------- - --------------- ---------- - ---------- -- --------------- --- ------------------- - ------ ---------- - --------- - ----- - -展开代码
可以看到,整个函数可分为四个部分:
- 将 Reducer 做一次过滤,去除不合法的
undefined
、null
、non-object
; - 获取 Reducer 的 key,保存到
reducerKeys
中; - 遍历
reducerKeys
数组,对每一个 Reducer 进行处理,存储到finalReducers
中; - 返回一个新的 Reducer,将所有最终处理出的 state 合并成一个对象。
applyMiddleware
applyMiddleware
用于应用中间件。其主要思路是通过柯里化来扩展 createStore
函数,使得其支持中间件的使用,可以记录日志、异步操作等。以下是其源码:
-- -------------------- ---- ------- ------ ------- -------- ------------------------------- - ------ --------------------- - ------ ----------------- --------------- --------- - ----- ----- - -------------------- --------------- --------- --- -------- - -------------- --- ----- - -- ----- ------------- - - --------- --------------- --------- -------- -- ---------------- - ----- - -------------------------- -- -------------------------- -------- - --------------------------------- ------ - --------- -------- - - - -展开代码
我们可以看到,整个函数有以下几个部分:
- 声明一个变量
middlewares
,存储所有中间件; - 返回一个高阶函数,该函数接收一个
createStore
函数,返回一个新的createStore
; - 在新的
createStore
中,声明一个存储所有中间件扩展函数的chain
数组; - 定义
middlewareAPI
对象,存储store.getState
和最新的store.dispatch
(因为后面会不断扩展); - 遍历所有中间件,将其执行,返回 Middlewares返回的是store对象的某个方法扩展函数,每个扩展函数都会接收到store.dispatch函数作为参数,返回一个新函数,接收一个action,执行扩展后的操作,并调用next函数(传入createStore到扩展函数返回的第一个函数),可以看到,最后通过compose 一次性将所有next合并成一个函数;
- 最后返回增强后的 store。该 store 中的
dispatch
已经被执行了中间件扩展。
总结
Redux 的源码解读,让我们更深入地了解其设计思路和具体实现。虽然函数逻辑有点复杂,但核心思路还是比较简单的,可提高我们的代码设计能力和代码阅读能力。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/6497d0a148841e98944d69a2