Redux 是一种流行的 JavaScript 应用程序状态管理工具。它的设计目标是让应用程序的状态变得可预测和可控。Redux 的核心概念是 store,它是一个存储应用程序状态的容器。Redux 的另一个重要概念是 reducer,它是一个纯函数,用于处理 store 中的状态变化。在本文中,我们将介绍 Redux 中的一个重要插件 Reselect,并展示如何使用它来处理冗余计算。
什么是 Reselect
Reselect 是一个用于创建可记忆的、高效的、可组合的选择器函数的库。选择器函数是一个纯函数,它接收一个或多个 state 参数,并返回从这些参数中派生的值。Reselect 的主要优点是它能够避免进行冗余计算。当一个选择器函数的输入参数没有改变时,Reselect 会返回缓存的结果,而不是重新计算。
Reselect 的另一个优点是它可以用于组合选择器函数。这使得我们可以将一个复杂的计算任务拆分成多个小的选择器函数,并在需要时组合它们。这种模块化的方法可以使我们更容易地维护代码,并且使代码更可读。
如何使用 Reselect
使用 Reselect 需要进行以下步骤:
安装 Reselect 库。
npm install reselect --save
创建选择器函数。
选择器函数通常是一个纯函数,它接收一个或多个 state 参数,并返回从这些参数中派生的值。例如,假设我们有一个 Redux store,其中包含一个名为 todos 的数组。我们可以编写一个选择器函数,用于计算完成的任务数量。这个选择器函数可以像这样:
import { createSelector } from 'reselect'; const getTodos = state => state.todos; const getCompletedTodosCount = createSelector( [getTodos], todos => todos.filter(todo => todo.completed).length );
在这个例子中,我们使用 createSelector 函数创建了一个选择器函数 getCompletedTodosCount。这个函数接收一个名为 getTodos 的选择器函数作为输入,并返回完成的任务数量。我们使用 filter 函数过滤 todos 数组中的已完成任务,并使用 length 属性获取任务数量。
在组件中使用选择器函数。
一旦我们创建了选择器函数,我们可以在组件中使用它来获取派生的值。例如,假设我们有一个名为 TodoList 的组件,用于显示所有的任务。我们可以将选择器函数传递给 connect 函数,以便在组件中访问它的返回值。例如:
import { connect } from 'react-redux'; import { getCompletedTodosCount } from '../selectors'; const mapStateToProps = state => ({ completedCount: getCompletedTodosCount(state) }); export default connect(mapStateToProps)(TodoList);
在这个例子中,我们将 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