Redux 教程:使用 Reselect 来处理冗余计算

· 约 7 分钟读完

Redux 是一种流行的 JavaScript 应用程序状态管理工具。它的设计目标是让应用程序的状态变得可预测和可控。Redux 的核心概念是 store,它是一个存储应用程序状态的容器。Redux 的另一个重要概念是 reducer,它是一个纯函数,用于处理 store 中的状态变化。在本文中,我们将介绍 Redux 中的一个重要插件 Reselect,并展示如何使用它来处理冗余计算。

什么是 Reselect

Reselect 是一个用于创建可记忆的、高效的、可组合的选择器函数的库。选择器函数是一个纯函数,它接收一个或多个 state 参数,并返回从这些参数中派生的值。Reselect 的主要优点是它能够避免进行冗余计算。当一个选择器函数的输入参数没有改变时,Reselect 会返回缓存的结果,而不是重新计算。

Reselect 的另一个优点是它可以用于组合选择器函数。这使得我们可以将一个复杂的计算任务拆分成多个小的选择器函数,并在需要时组合它们。这种模块化的方法可以使我们更容易地维护代码,并且使代码更可读。

如何使用 Reselect

使用 Reselect 需要进行以下步骤:

  1. 安装 Reselect 库。

  2. 创建选择器函数。

    选择器函数通常是一个纯函数,它接收一个或多个 state 参数,并返回从这些参数中派生的值。例如,假设我们有一个 Redux store,其中包含一个名为 todos 的数组。我们可以编写一个选择器函数,用于计算完成的任务数量。这个选择器函数可以像这样:

    在这个例子中,我们使用 createSelector 函数创建了一个选择器函数 getCompletedTodosCount。这个函数接收一个名为 getTodos 的选择器函数作为输入,并返回完成的任务数量。我们使用 filter 函数过滤 todos 数组中的已完成任务,并使用 length 属性获取任务数量。

  3. 在组件中使用选择器函数。

    一旦我们创建了选择器函数,我们可以在组件中使用它来获取派生的值。例如,假设我们有一个名为 TodoList 的组件,用于显示所有的任务。我们可以将选择器函数传递给 connect 函数,以便在组件中访问它的返回值。例如:

    在这个例子中,我们将 getCompletedTodosCount 函数传递给 mapStateToProps 函数,以便在组件中访问它的返回值。我们将返回值存储在 completedCount 属性中,并将其作为组件的 props 传递。

示例代码

下面是一个完整的示例代码,演示如何使用 Reselect 来处理冗余计算。这个示例代码创建了一个简单的 Redux 应用程序,用于管理任务列表。它包含一个名为 todos 的数组,其中存储了所有的任务,以及一个名为 filter 的字符串,用于过滤任务列表。我们使用 Reselect 来创建选择器函数,用于计算已完成任务的数量,并根据过滤器筛选任务列表。

在这个示例代码中,我们首先定义了一个名为 initialState 的对象,它包含了应用程序的初始状态。然后,我们定义了一个 reducer 函数,用于处理 store 中的状态变化。在 reducer 函数中,我们使用 switch 语句处理两种类型的 action:SET_FILTER 和 TOGGLE_TODO。

接下来,我们定义了三个选择器函数:getTodos、getFilter 和 getVisibleTodos。getTodos 函数用于获取 todos 数组,getFilter 函数用于获取 filter 字符串。getVisibleTodos 函数是一个组合函数,它使用 getTodos 和 getFilter 函数计算可见的任务列表。它首先使用 filter 函数过滤 todos 数组,然后使用 map 函数将匹配的文本替换为带有黄色背景的字符串。

最后,我们定义了一个名为 getCompletedTodosCount 的选择器函数,用于计算已完成任务的数量。它使用 filter 函数过滤 todos 数组,并使用 length 属性获取任务数量。我们使用 createStore 函数创建了一个 Redux store,并使用 subscribe 函数订阅了 store 的变化。最后,我们使用 dispatch 函数分发了三个 action,并使用 getVisibleTodos 和 getCompletedTodosCount 函数获取派生的值。

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