Redux 中的 reducer 实例分析

Redux 是一种流行的 JavaScript 应用程序状态管理库,它允许您管理应用程序的状态和行为。在 Redux 中,reducer 是一个纯函数,用于处理应用程序状态的更改。在本文中,我们将深入研究 Redux 中 reducer 的实现,以及如何编写一个高效且可复用的 reducer。

reducer 的基础知识

在 Redux 中,reducer 是一个函数,它接收两个参数:当前状态和一个 action 对象。根据这些输入,reducer 返回一个新状态。这个过程是纯函数的,意味着 reducer 的输出只依赖于它的输入,没有任何副作用。下面是一个简单的 reducer 实现示例:

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

在这个例子中,我们创建了一个计数器 reducer,它维护一个简单的计数器状态对象。当接收到 INCREMENT 操作时,它会增加计数器的值,当接收到 DECREMENT 操作时,它会减少计数器的值。

在默认情况下,我们返回现有的状态 —— 这就是让 reducer 更具可复用性的关键之一。如果你的状态对象没有更改,你可以直接返回原始状态。

reducer 的最佳实践

虽然 Redux 不会强制要求您如何编写 reducer,但有一些最佳实践值得遵循。下面是一些关键的最佳实践:

1. reducer 中使用 switch 语句

在 Redux 的 reducer 实现中,使用 switch 语句是一种广泛采用的做法。每个条件都对应一个操作,并根据 action.type 来检查所需的操作。这种方式使 reducer 代码更易读和可维护。

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

2. reducer 不应该修改现有的状态

修改现有状态的行为,将导致不可预测的结果。下面的代码将现有状态属性的值设置为 1,这是禁止的:

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

相反,应该返回一个新的状态对象。

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

3. reducer 必须是纯函数

Reducer 是一个纯函数,因为它的输出仅依赖于它的输入。以下情况都是不允许的:

  • 修改输入参数 state
  • 调用一个不纯的函数
  • 产生副作用
-- ----- -------- --- --- ---- ----------

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

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

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

4. 使用 object spread 运算符更新状态

在更新一个属性之前,通过 object spread 运算符创建一个新的状态对象。这可确保我们不会意外地修改原始状态。

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

5. 区分修改和创建操作

由于我们返回一个新的状态对象来更新状态,最后一个最佳实践是区分修改和创建操作。

修改操作使用当前状态的旧值和一个 action 对象来生成一个新的状态对象。

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

创建操作使用一个 action 对象的特殊数据 —— 权威数据(Canonical Data)来生成一个新的状态对象,例如从服务器获取新的数据。

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

reducer 的高级用法

1. 使用 combineReducers()

combineReducers() 函数允许您将多个 reducer 组合成一个单一的 reducer。

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

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

如果我们想要访问所有 reducer 中的某一个 state,我们可以使用例如 useSelector() 这样的 Redux hook。

2. 使用 createSlice()

使用 Redux Toolkit 可以轻松地创建 reducer 和 action。使用 createSlice() 函数可以生成 action 和 reducer 的组合,以更快地编写 Redux 逻辑。

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

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

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

createSlice() 函数最终生成以下对象:

  • name - slice 名称
  • initialState - state 的初始值
  • reducers - 包含 reducer 逻辑的对象
  • actions - 生成的 action 对象

3. 理解 Redux 的数据流

为了更好地理解 Redux 的工作方式,让我们详细了解 Redux 的数据流:

图中所示的数据流如下:

  • 应用程序中触发 action。
  • action 发送到 store。
  • store 将 action 与 reducer 匹配。
  • reducer 根据传入的 action 更改状态,并返回新的应用程序状态。
  • store 将新状态与之前状态进行比较,并将变更通知视图。

4. 使用 Redux DevTools

Redux DevTools 是一个开发工具,它可以大大提高 Redux 的调试效率。它允许开发者查看应用程序状态的历史记录,并针对以前的状态进行操作。要启用 Redux DevTools,请按照以下步骤操作:

  • 安装 Chrome 插件。
  • 创建 Redux store 时传递 composeWithDevTools() 作为 enhancer。
------ - ----------- - ---- --------
------ - ------------------- - ---- ---------------------------

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

使用 Redux DevTools,您可以调试和改进您的应用程序,以及轻松地找到错误。

结论

理解和使用 Redux 的 reducer 是成为优秀前端开发者的必要技能之一。通过遵循最佳实践和使用高阶组件,您可以创建高效和可维护的 Redux 应用程序。另外,Redux DevTools 工具可以极大地提高开发效率,使您更容易调试和改进您的应用程序。

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/67131888ad1e889fe20a7f5b