npm 包 typed-redux-kit.mapped-reducer 使用教程

阅读时长 11 分钟读完

在使用 React 和 Redux 开发项目时,我们经常需要定义 reducer 来管理应用的状态。一个 reducer 对应一个 state,并定义了其如何响应 action。然而,在实际开发中,有时候我们需要管理多个 state,而这些 state 的结构可能是相似的,这时候我们就可以使用一个 higher-order reducer 来封装这一部分逻辑。

typed-redux-kit.mapped-reducer 是一个用 TypeScript 编写的 higher-order reducer,它可以映射多个子 reducer 的输出,将它们整合到一个 parent state 中。它的设计灵感来自于 scaled-reduxmap-reducers 这两个库。

本文将介绍如何使用 typed-redux-kit.mapped-reducer,并提供示例代码。

安装

你可以使用 npmyarn 安装 typed-redux-kit.mapped-reducer

示例

假设我们有这样两个 state:

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

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

我们可以定义两个 reducer 分别对应这两个 state:

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

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

现在,我们想要将这两个 state 合并到一个 parent state 中,定义一个新的 reducer:

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

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

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

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

在这个例子中,我们将 initialState 定义为一个对象,包含两个子 state:userproduct。我们使用 mappedReducer 函数来将这两个子 reducer 映射到 parent reducer 中。

现在我们就可以在组件中使用这个 reducer 了:

深入理解

上面的示例中我们简单介绍了如何使用 mappedReducer,现在让我们来看看更多的使用场景和 API。

传递额外参数

在实际开发中,我们可能需要传递一些额外的参数给子 reducer。例如,在用户登录时,我们需要将用户信息传递给 userReducer,在后端返回订单列表时,我们需要将订单列表传递给 productReducer。这时候我们可以使用 mappedReducer 的第二个参数来传递这些参数。

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

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

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

我们将 userReducerproductReducer 的第三个参数都命名为 { user }{ orders },这样在调用 reducer 时,这些参数就会被传递给它们。

合并多个 reducer

mappedReducer 的第二个参数可以是一个对象,也可以是一个函数。如果是一个对象,表示将子 reducer 映射到指定的子 state 中;如果是一个函数,表示将多个子 reducer 合并到一起。

假设我们有这样三个 state:

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

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

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

我们可以定义三个 reducer 分别对应这三个 state:

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

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

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

在这里,我们的需求是将 product state 下的多个 product 映射到 orders state 中,而 user state 则需要单独处理。我们可以使用 mergeReducers 函数来将这些 reducer 合并到一起。

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

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

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

在这里,我们使用 mergeReducers 函数来将 productReducerorderReducer 合并到一起,并将结果映射到 orders.products 中。这时候,我们需要在 orderReducer 中处理 UPDATE_PRODUCT 这个 action,因为 productReducer 并不能智能地处理这个 action。我们使用 updateProduct 函数来包装 UPDATE_PRODUCT,将 index 和其他参数一起传递给它。

现在我们可以在组件中使用这个 reducer:

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

类型声明

通过 mappedReducermergeReducers 函数,我们可以尽可能地减少代码重复,提高代码复用性和可维护性。但是,当我们使用 TypeScript 开发时,我们也需要保持类型安全。

typed-redux-kit.mapped-reducer 会自动生成合并后 state 和 action 的类型声明。我们定义 RootState 时,可以直接使用 ReturnType<typeof rootReducer> 得到类型声明:

这样,在我们使用 useReducer 函数时,statedispatch 的类型声明就会自动推导出来。

结语

在这篇文章中,我们介绍了如何使用 typed-redux-kit.mapped-reducer 来管理多个 state,并提供了详细的示例代码。希望本文对你理解 higher-order reducer 有所帮助!如果你想要了解更多关于 Redux 的内容,可以查看 Redux 官方文档和 React 官方文档。

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

纠错
反馈