Redux 中的 reducer 实例分析

阅读时长 10 分钟读完

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

纠错
反馈

纠错反馈