使用 reselect 优化 Redux 中的性能问题

在进行前端开发过程中,处理大量数据的场景是非常常见的。在这种情况下,使用 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 接收两个参数,getUsersgetFilter 返回的数据子集。如果 filter 的值为 "all",则返回所有的 users,否则返回 sex 等于 filter 的 users。

组合选择器

我们将使用组合选择器将所有的选择器函数组合成一个新函数,在 mapStateToProps 中调用它来获取最新的经过过滤的用户列表。

----- --------------- - ----- -- --
  ------ -----------------------
--

总结

reselect 是一个优秀的库,它提供了计算衍生数据的技术,可以优化 Redux 中的性能问题。我们可以通过编写选择器函数并使用 createSelector 方法来缓存衍生数据,减少不必要的计算和传输,提高应用的性能。

同时,reselect 也能更好地使代码可读性更好,并且可以更清晰地表达对数据的过滤和转换操作。这对于长期维护和维护大型应用程序至关重要。

来源:JavaScript中文网 ,转载请联系管理员! 本文地址:https://www.javascriptcn.com/post/66435e06d3423812e415e56e


猜你喜欢

  • Redux 容错方案:重试机制

    在前端开发过程中,我们经常会使用 Redux 进行状态管理。但是,由于网络不稳定等原因,有时候 Redux 的异步请求会失败,导致状态更新失败。为了解决这个问题,我们可以使用 Redux 容错方案中的...

    5 个月前
  • 在 React Native 中使用 Animated 进行动画效果的实现

    React Native 是一种基于 JavaScript 的开源框架,它可以让开发者使用相同的代码构建 iOS 和 Android 应用程序。其中,Animated 是 React Native 中...

    5 个月前
  • Sass 中的模块化思想

    前言 在前端开发中,CSS 是不可或缺的一部分。但是,CSS 的样式表往往会变得越来越复杂,难以维护和扩展。为了解决这个问题,Sass 诞生了。Sass 是一种 CSS 预处理器,它可以让开发者使用类...

    5 个月前
  • 解决 Cypress 中测试时无法发送请求的问题

    在前端自动化测试中,Cypress 是一款非常流行的工具。它提供了强大的功能,例如自动化测试、断言、模拟用户行为等等。但在实际使用中,有些开发者可能会遇到一个问题:无法发送请求。

    5 个月前
  • 初识 AngularJS—— 双向数据绑定的实现

    前言 AngularJS 是一个流行的前端框架,它的核心特性之一就是双向数据绑定。双向数据绑定可以让我们在页面上修改数据时,自动更新相关的数据和页面元素,而不需要手动更新 DOM。

    5 个月前
  • 使用 Redis 实现分布式锁的技巧

    在分布式系统中,分布式锁是一个非常重要的概念。它可以避免多个节点同时访问共享资源而导致的数据竞争和错误。Redis 是一个高性能的内存数据库,它提供了一些原子操作和数据结构,可以用来实现分布式锁。

    5 个月前
  • 通过 Xcode 优化 iOS 应用程序性能

    在开发 iOS 应用程序时,应用程序的性能是一个非常重要的方面。应用程序的性能不仅关系到用户体验,还直接影响到应用程序的用户留存率和盈利能力。因此,对于前端开发者来说,通过 Xcode 优化 iOS ...

    5 个月前
  • 在 Next.js 中启用 ESLint 的最佳实践

    在 Next.js 中启用 ESLint 的最佳实践 在前端开发中,代码规范是非常重要的。ESLint 是一个非常流行的代码规范检查工具,可以帮助我们保证代码的质量和一致性。

    5 个月前
  • 利用 Custom Elements 实现数据绑定

    在前端开发中,数据绑定是一个非常常见的需求。它能够将数据与 UI 元素进行关联,使得数据的变化能够自动地反映到 UI 上。在过去,我们常常需要使用诸如 Vue、React 等框架来实现数据绑定。

    5 个月前
  • 使用 Socket.io 进行远程编程和调试

    前言 在前端开发过程中,我们经常会遇到需要联调、共享代码等情况。如果团队分布在不同的地方,或者需要和客户进行远程联调,那么如何进行远程编程和调试是一个值得考虑的问题。

    5 个月前
  • 无障碍性设计及测试工具

    随着互联网的普及,越来越多的人开始使用电子设备来获取信息和交互。然而,残障人士在使用电子设备时可能会遇到一些困难,例如视力障碍、听力障碍或运动障碍等。为了让所有人都能够方便地使用电子设备,我们需要关注...

    5 个月前
  • 在 Mocha 和 Chai 测试时如何处理异步代码?

    在前端开发中,我们经常需要进行单元测试来确保代码的正确性和可靠性。而 Mocha 和 Chai 是最常用的 JavaScript 测试框架之一。但是,测试中经常会遇到异步代码的问题,如何正确处理异步代...

    5 个月前
  • 如何在 VS Code 中使用 ESLint 自动化检查代码

    简介 ESLint 是一个开源的 JavaScript 代码检查工具,它可以帮助我们检查代码中的潜在问题和错误,提高代码质量和可读性。在前端开发中,使用 ESLint 可以避免一些常见的错误,如语法错...

    5 个月前
  • Angular 6 与 RxJS 6:一起使用的指南

    在前端开发中,Angular 和 RxJS 都是非常流行的技术。Angular 是一款强大的前端框架,可以帮助开发者构建复杂的应用程序。RxJS 是一个基于观察者模式的 JavaScript 库,可以...

    5 个月前
  • 如何使用 CSS Reset 优化 radio 和 checkbox 的样式?

    在开发 Web 应用程序时,我们经常需要使用表单元素,如 radio 和 checkbox。然而,这些元素的默认样式在不同浏览器之间存在差异,甚至在同一浏览器中也可能存在差异。

    5 个月前
  • 如何使用 Flexbox 布局快速实现导航栏样式

    前言 在前端开发中,导航栏是非常常见的一个组件,如何实现一个美观且易于维护的导航栏样式是每个前端开发人员都需要掌握的技能。本文将介绍如何使用 Flexbox 布局快速实现导航栏样式。

    5 个月前
  • 使用 Jest 测试 Node.js 应用的方法

    Jest 是一个流行的 JavaScript 测试框架,它可以用于测试 Node.js 应用程序。本文将介绍如何使用 Jest 测试 Node.js 应用程序,并提供示例代码和深入指导。

    5 个月前
  • 解决 Express.js 中文件上传大文件失败的问题

    在使用 Express.js 进行文件上传时,当上传的文件较大时,会出现上传失败的情况。这是由于 Express.js 默认的文件上传限制较小所导致的。本文将介绍如何解决这个问题并提供示例代码。

    5 个月前
  • Promise 中的 resolve 和 reject 的使用方法

    Promise 是 JavaScript 中一种常见的异步编程方式,它可以让我们更方便地处理异步代码,避免回调地狱的问题。在 Promise 中,resolve 和 reject 是两个非常重要的方法...

    5 个月前
  • Angular 中的 TypeScript 编写单元测试的技巧

    单元测试在前端开发中扮演着至关重要的角色,可以帮助开发者快速发现和解决代码中的问题,提高代码质量和可维护性。而在 Angular 中,使用 TypeScript 编写单元测试可以更加方便和高效。

    5 个月前

相关推荐

    暂无文章