随着前端应用复杂度的上升,Redux 的使用已经成为了现代前端开发不可或缺的一环。Redux 最大的特点是对数据流进行了规范化的管理,但是也带来了一些性能瓶颈。例如:每当 Redux Store 的状态发生变化时,所有订阅该状态的组件都会重新渲染,其次在 mapStateToProps 中使用不当也可能导致大量的计算。
为了避免上述问题,我们可以引入 reselect 库对 Redux 的数据进行优化。本篇文章将向大家详细介绍 reselect 的使用指南。
reselect 简介
reselect 是一个专门用于优化 Redux 状态选择器函数的 JavaScript 库。它的主要作用是提高 mapStateToProps 函数的性能,同时减少组件不必要的重新渲染。
reselect 实现了一个基于“记忆化(memoization)”的缓存机制。当输入参数相同时,reselect 将直接返回缓存中的计算结果,而不会重新执行计算逻辑,从而提升应用的性能。
安装 reselect
安装 reselect 十分简单,只需在项目中运行以下命令:
npm install reselect --save
使用 reselect
要开始使用 reselect,需要先定义一个 selector 函数。Selector 函数的参数是 Redux state,定义的逻辑是将 state 中的数据转换、过滤或合并成新的数据,最后返回新的数据。
Selector 函数可以接受一个或多个参数,每个参数代表一个需要转换的 state 属性,并且输入参数必须是纯函数。下面是一个简单的 Selector 函数例子:
const todosSelector = state => state.todos
在调用 Selector 函数时,我们可以直接调用它来获取新的数据。
const todos = todosSelector(store.getState())
接下来,我们可以通过 createSelector 函数把 todosSelector 函数包装一下,使其获得缓存功能,示例如下:
-- -------------------- ---- ------- ------ - -------------- - ---- ---------- ----- ------------- - ----- -- ----------- ----- --------------- - --------------- ---------------- ----- -- ----------------- -- ---------------- - ----- ------------ - ---------------------------------
上面的代码中,getVisibleTodos 将会对 todos 属性进行过滤,并把结果进行缓存,只有在 todosSelector 改变时才重新计算过滤后的结果。
reselect 的高级用法
多 selector 串联
如果多个 Selector 依赖同一个 state 属性,当该属性变化时,所有依赖它的 Selector 都将重新计算并重新渲染。
下面的示例将演示如何同时匹配搜索栏中的文本和特定状态的 todo。其中,getSearchText 和 getTodos 都为私有 Selector。当任意一个 Selector 的结果发生改变时,getVisibleTodos 的计算都将被调用。
const getSearchText = state => state.searchText const getTodos = state => state.todos export const getVisibleTodos = createSelector( [getTodos, getSearchText], (todos, searchText) => todos.filter(todo => todo.text.indexOf(searchText) !== -1) )
缓存效果的多次调用
虽然 createSelector 函数能够很好地缓存 Selector 函数的结果,但对于一些具有复杂计算的 Selector 函数,重复调用 createSelector 的过程也可能会消耗相当多的时间。同时,与第一种情况相同的是,所有依赖它的 Selector 都将重新计算并重新渲染。
下面的示例将展示如何在多个 Selector 中共享计算结果:
-- -------------------- ---- ------- ------ - -------------- - ---- ---------- ------ ----- -------- - ----- -- ----------- ------ ----- -------------- - --------------- ----------- ----- -- ----------------- -- -------------- - ------ ----- ---------------- - --------------- ----------- ----- -- ----------------- -- --------------- -
在上面的代码中,getActiveUsers 和 getInactiveUsers 都依赖于 getUsers,因此它们可以通过传递相同的参数来共享计算结果。这将大大减少 createSelector 的调用次数并提高性能。
总结
在前端工程化的大趋势下,对于一个高性能的应用来说,优化是至关重要的一部分。reselect 作为 Redux 的性能优化库,可以帮助你更好地管理你的应用的状态,并提高计算性和渲染性能。在实际项目中,有了 reselect 的加持,我们就可以更好地去处理状态与组件之间的关系,而不是频繁的、不必要的重新计算状态。
如果您是一名前端开发者,并且正在寻找一个性能强大的状态管理库,那么 Redux 和 reselect 一定是您的不二之选。希望本篇文章能够帮助到您更好地使用 reselect,提升应用的性能,进而提升用户的体验。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/649eb1c948841e9894b3dac3