在进行前端开发过程中,处理大量数据的场景是非常常见的。在这种情况下,使用 Redux 管理应用的状态,是非常方便的一种解决方案。然而,我们会发现随着项目变得越来越庞大,性能问题也逐渐显现出来。这篇文章就将介绍如何使用 reselect 优化 Redux 中的性能问题。
Redux 与性能问题
在复杂的应用程序中,Redux 可能会被多个组件同时使用。每个组件都可能使用 Redux 存储中的相同部分数据。由于 Redux 是单一的数据存储,每个组件都会访问存储中的整个数据对象。这将导致对数据的多次不必要的传输以及不必要的计算。
为了避免这种问题,我们可以使用 reselect 库来提高 Redux 的性能。
什么是 reselect?
Reselect 是一个受 FP(函数式编程)启发的库,用于计算 Redux 存储中的衍生数据。Reselect 实际上是一个缓存库,它可以听取多个选择器函数,这些选择器函数负责从 Redux 存储中选择数据,并将这些数据用作输入来计算衍生数据。Reselect 缓存这些输入和输出,以便可以在下一次调用时快速计算衍生数据,而无需重新计算数据。
在具体实现中,我们需要编写选择器函数。这些选择器函数接受应用状态的参数,并返回衍生数据。选择器返回的结果将被缓存,以便可在下次使用中重复利用。
reselect 原理
Reselect 实现是基于以下原理:
输入相同的参数将始终返回相同的输出
与输入参数无关的组件状态将不会影响计算结果
在使用 Reselect 时,我们自定义选择器函数,从 Redux 存储中选取某些部分数据,并进行计算得到一些衍生数据。如果被选取的数据未发生变化,则不会重复计算该函数。这提高了应用的性能,因为在 Redux 存储中,只有真正发生变化的数据才会重新计算和更新。
如何使用 reselect?
使用 reselect 需要导入 createSelector 方法。createSelector 方法接受一组前置选择器,并返回一个接受 state 作为输入的新函数 (也叫做"组合选择器")。这个新函数取决于预先定义的选择器返回的值,并返回一个最终的汇总结果。
例如,假设 Redux 存储中有一个包含下列属性的数据对象
- ------ - - --- -- ----- ----- --- ---------- ---- -- - --- -- ----- ----- --- ---------- ----- -- - --- -- ----- ----- --- ---------- ----- -- - --- -- ----- ----- --- ---------- ---- -- - --- -- ----- ----- --- ---------- ----- - -- ----------------- ---------------- -
我们可以创建一个选择器,该选择器返回"已完成"过滤器状态映射到"todos"数组的项
----- --------------- - --------------- ----- -- ------------ ----- -- ----------------------- ------- ----------------- -- - ------ ------------------ - ---- ----------------- ------ ----------------- -- --------------- ---- -------------- ------ ----------------- -- ---------------- -------- ------ ----- - - -
createSelector
接收多个函数作为参数,每个函数都接收 Redux 存储中的 state 作为参数并返回对象上的数据子集。在我们的示例中,我们传递了三个各自相互独立的函数,其中两个函数分别读取 Redux 存储中的 "todos" 和 "visibilityFilter"。第三个函数接收这两个值作为参数,然后根据 visibilityFilter 的值过滤 todos 数组,并返回一个新的 filteredTodos 组合对象。
现在,我们可以使用 getVisibleTodos
来获取过滤后的任务列表
----- --------------- - ----- -- -- ------ ---------------------- --
示例代码
下面是一个使用 reselect 的示例代码,我们将从 state 中选取一部分信息并计算其衍生数据。
数据
我们的应用状态由以下数据对象组成。
- ------ - -- ---- -- ----- ------- ---- --- ---- -------- -- ---- -- ----- ------- ---- --- ---- ---------- -- ---- -- ----- ------ ---- --- ---- -------- -- ---- -- ----- -------- ---- --- ---- ---------- -- ------- ----- -
其中,users 是一个对象,每个对象都是一个用户信息。filter 是一个字符串,可以是 "all" 或 "male" 或 "female"。
选择器函数
我们将编写三个选择器函数,分别取得用户信息、过滤条件和经过过滤的结果。
----- -------- - ----- -- ----------- ----- --------- - ----- -- ------------ ----- ---------------- - --------------- ---------- ----------- ------- ------- -- - -- ------- --- ------ ------ -------------------- ------ -------------------------------- -- -------- --- ------- - -
getFilteredUsers
接收两个参数,getUsers
和 getFilter
返回的数据子集。如果 filter 的值为 "all",则返回所有的 users,否则返回 sex 等于 filter 的 users。
组合选择器
我们将使用组合选择器将所有的选择器函数组合成一个新函数,在 mapStateToProps 中调用它来获取最新的经过过滤的用户列表。
----- --------------- - ----- -- -- ------ ----------------------- --
总结
reselect 是一个优秀的库,它提供了计算衍生数据的技术,可以优化 Redux 中的性能问题。我们可以通过编写选择器函数并使用 createSelector 方法来缓存衍生数据,减少不必要的计算和传输,提高应用的性能。
同时,reselect 也能更好地使代码可读性更好,并且可以更清晰地表达对数据的过滤和转换操作。这对于长期维护和维护大型应用程序至关重要。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/66435e06d3423812e415e56e