Redux 源码分析之 createStore 与 applyMiddleware

阅读时长 11 分钟读完

Redux 是一个非常流行的 JavaScript 应用程序状态管理库,它可以帮助开发者管理复杂的应用程序状态,使得应用程序状态管理更加简单和可维护。在 Redux 中,我们可以使用 createStore 方法来创建一个状态仓库,然后使用 applyMiddleware 方法来添加中间件,以便处理异步操作和其他一些高级用例。

本文将介绍 Redux 的 createStore 和 applyMiddleware 方法的源代码实现,并且会深入分析其内部实现和使用方式,以便开发者更好地理解Redux的工作原理并加强Web前端开发技能。

createStore 方法

createStore 方法是 Redux 库中创建状态仓库的函数。它的定义如下:

其中,reducer 是 Redux 应用的状态管理函数,用于定义应用程序状态的变化方式。preloadedState 是预加载的应用程序初始状态,可以是任何可以序列化的数据类型。enhancer 是可选的中间件增强器,用于增强 createStore 的功能。

createStore 方法内部实现

Redux 库中的 createStore 主要包括三个核心部分:store、dispatch 和 subscribe,下面分别进行详细介绍。

store

store 是保存应用程序状态的容器。它至少有以下方法:

  • getState(): 返回当前状态值。
  • dispatch(action): 触发状态更新。
  • subscribe(listener): 注册一个监听器,当状态变化时会自动执行。

在 createStore 函数中,我们定义一个内部变量 state,用于存储状态值,以及一个数组 listeners,用于存储所有注册的监听器。代码如下:

dispatch

dispatch 方法是用来触发状态更新的函数,它接受一个 action 对象作为参数,如下所示:

在 dispatch 函数内部,我们首先调用 reducer 方法来计算新的状态值,然后执行所有注册的监听器,通知它们应用程序状态已经更新。

subscribe

subscribe 方法用来注册应用程序状态变化的监听器,它接收一个函数作为参数,函数会在状态变化时被调用。代码如下:

在 subscribe 方法中,我们先将监听器加入 listeners 数组,然后返回一个取消监听器的函数。当调用返回的函数时,它会从监听器数组中移除对应的监听器。

createStore 完整代码

下面是 createStore 方法的完整代码,包括状态容器 store、dispatch 和 subscribe 方法的定义。

-- -------------------- ---- -------
-------- -------------------- --------------- --------- -
  --- ----- - ---------------
  ----- --------- - ---

  -- ------- -------- --- ----------- -
    ------ ------------------------------ ----------------
  -

  -------- ---------- -
    ------ ------
  -

  -------- ---------------- -
    ----- - -------------- --------
    -------------------------- -- ------------
  -

  -------- ------------------- -
    -------------------------
    ------ -------- ------------- -
      ----- ----- - ----------------------------
      ----------------------- ---
    --
  -

  -------------

  ------ -
    ---------
    ---------
    ----------
  --
-

applyMiddleware 方法

applyMiddleware 是 Redux 库中添加中间件的高级函数,它可以帮助开发者完成常见的复杂场景,如异步处理、路由处理等。它采用类似洋葱模型的方式,把多个中间件串联起来构成一个调用链。其定义如下:

-- -------------------- ---- -------
-------- ------------------------------- -
  ------ ----------- -- --------- --------------- -- -
    ----- ----- - -------------------- ----------------
    --- -------- - ---------------

    ----- ------------- - -
      --------- ---------------
      --------- ------ -- -----------------
    --

    ----- ----- - -------------------------- -- ---------------------------
    -------- - ----------------------------------

    ------ -
      ---------
      ---------
    --
  --
-

applyMiddleware 函数的返回值是一个高阶函数,在接收 createStore 作为参数后,返回一个函数,这个函数接收 reducer 和 preloadedState 两个参数,并且返回一个包含 store 和 dispatch 的状态容器对象。

applyMiddleware 方法内部实现

applyMiddleware 函数的实现是基于 createStoe 方法的,它会使用传入的 createStore 方法来创建一个状态容器。

接下来,它定义一个名为 dispatch 的变量,并将其赋值为 store.dispatch,然后创建一个 middlewareAPI 对象,用于在各个中间件之间传递 getState 和 dispatch 函数。

同时,applyMiddleware 方法还会将所有中间件作为数组传入,通过 map 方法遍历数组,并且将 middlewareAPI 传入到各个中间件函数中,形成一个中间件的调用链。

最后,applyMiddleware 方法会调用 compose 函数来合并整个中间件调用链。其实现方式类似于管道,即先传入最右边的中间件,返回一个新的函数,接着再把当前函数传给左边的中间件,一直执行到最左边的中间件,最终返回一个新的函数用于替换 dispatch。

示例代码

下面是一个简单示例,我们将使用 Redux 和 applyMiddleware 函数来管理一个模拟的 TODO 列表应用程序。其中,包含两个自定义的中间件:logger 中间件和 async 中间件。

logger 中间件用于打印出状态更新前后的状态变化情况,代码如下:

async 中间件用于处理异步操作,它会延迟一段时间后再执行 dispatch 函数,代码如下:

-- -------------------- ---- -------
----- ----- - ----- -- ---- -- ------ -- -
  -- ------- ------ --- ----------- -
    ------ ------------- -- -
      ---------------------- ------------------
    -- ------
  -

  ------ -------------
--

下面是完整的示例代码:

-- -------------------- ---- -------
-------- ----------- - --- ------- -
  ------ ------------- -
    ---- -----------
      ------ ---------- - ----- ------------ ---------- ----- ---
    ---- --------------
      ------ ---------------- ------ --
        ----- --- ------------
          - - -------- ---------- --------------- -
          - ----
      --
    --------
      ------ ------
  -
-

-------- ---------------------- - ----------- ------- -
  ------ ------------- -
    ---- ------------------------
      ------ --------------
    --------
      ------ ------
  -
-

-------- ------------------------ -
  ------ ------ - --- ------- -- -
    ------ ---------------------------------------- ---- -- -
      -------------- - ------------------------- --------
      ------ ----------
    -- ----
  --
-

----- ------- - ----------------
  ------
  -----------------
---

----- ------ - ----- -- ---- -- ------ -- -
  -------------------------- --------
  ----- ------ - -------------
  ----------------- ------- ------------------
  ------ -------
--

----- ----- - ----- -- ---- -- ------ -- -
  -- ------- ------ --- ----------- -
    ------ ------------- -- -
      ---------------------- ------------------
    -- ------
  -

  ------ -------------
--

----- ----- - ----------------------- -----------------------------

------------------ -- -
  ---------------------------- ------------------
---

----------------
  ----- -----------
  ----- ------ -------
---

----------------
  ----- --------------
  ------ --
---

----------------
  ----- ------------------------
  ------- -----------------
---

------------------------- --------- -- -
  ------------- -- -
    ----------
      ----- -----------
      ----- ------ -------
    ---
  -- ------
---

在上面的示例代码中,我们首先定义了两个状态管理函数 todos 和 visibilityFilter,然后通过 combineReducer 函数将它们结合在一起,作为一个 rootReducer。接着我们定义了两个中间件 logger 和 async,用于处理状态更新的过程。

最后,我们通过 applyMiddleware 函数来增强 createStore 函数,这样可以在创建状态容器时自动应用中间件,并且使用返回的 store 对象来管理应用程序的状态更新。最终我们分别添加了几个 status action,来演示 store 的状态更新过程,最后输出了更新后的状态信息。

总结

Redux 是一个非常流行的 JavaScript 应用状态管理库,它可以帮助开发者管理复杂的应用程序状态。本文分别分析了其 createStore 和 applyMiddleware 方法的源代码实现,并且深入分析了其内部实现和使用方式,希望能够加强 Web 前端开发者的开发技能。同时,我们还演示了如何使用 Redux 和 applyMiddleware 函数来管理一个模拟的 TODO 列表应用程序,以便开发者更好地理解 Redux 的实现原理并加强实践能力。

来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/64ffcc0595b1f8cacde15fd8

纠错
反馈