Redux 中使用 Reselect 库实现数据缓存

在 Redux 应用中,我们通常需要根据 state 中的数据计算出一些派生数据,比如过滤、排序等。这些派生数据可以使用计算属性(computed property)来实现,但是每次使用计算属性都会重新计算,可能会影响性能。为了避免重复计算,我们可以使用 Reselect 库来实现数据缓存。

Reselect 简介

Reselect 是一个用于创建可记忆的(memoized)选择器函数的库。选择器函数接收 state 作为输入,并返回派生数据。Reselect 的主要作用是缓存选择器函数的计算结果,避免重复计算。

Reselect 的主要特点包括:

  • 可记忆的:相同的输入会返回相同的输出,避免重复计算。
  • 高效的:只有当输入数据发生变化时,才会重新计算。
  • 灵活的:可以组合多个选择器函数,创建更复杂的派生数据。

Reselect 的使用

使用 Reselect 需要先安装该库:

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

然后,我们可以创建一个选择器函数,用于计算派生数据。例如,我们有一个 state,包含一个列表和一个过滤条件:

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

我们希望根据过滤条件筛选列表中的元素,并返回筛选后的结果。可以使用下面的代码创建一个选择器函数:

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

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

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

在上面的代码中,我们使用 createSelector 创建了一个选择器函数 getFiltered。这个函数接收两个输入参数 getList 和 getFilter,分别用于获取列表和过滤条件。在计算派生数据时,我们使用 filter 方法筛选列表中的元素,并返回结果。

使用选择器函数时,我们可以像调用普通函数一样调用它:

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

在上面的代码中,我们传入 state 参数调用 getFiltered 函数,并获取筛选后的结果。

Reselect 的优化

使用 Reselect 可以避免重复计算,提高应用性能。但是,为了实现最佳性能,我们需要遵循一些优化原则。

原则一:选择器函数应该是纯函数

选择器函数应该是纯函数,即相同的输入应该返回相同的输出。这样可以避免因为副作用导致缓存无效。

例如,下面的代码中,选择器函数会改变 state 中的数据,导致缓存无效:

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

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

为了避免这种情况,我们应该将选择器函数设计成纯函数:

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

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

在上面的代码中,我们不再改变 state 中的数据,避免了副作用。

原则二:选择器函数应该是高效的

选择器函数应该是高效的,即只有当输入数据发生变化时,才会重新计算。为了实现这一点,我们应该尽量避免在选择器函数中进行复杂的计算,而是将复杂计算拆分成多个选择器函数,然后组合起来使用。

例如,我们有一个 state,包含一个列表和一个排序方式:

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

我们希望根据排序方式对列表进行排序,并返回排序后的结果。可以使用下面的代码创建选择器函数:

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

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

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

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

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

在上面的代码中,我们定义了三个选择器函数:getSortedByName、getSortedByAge 和 getSorted。getSortedByName 和 getSortedByAge 分别用于按照名称和年龄排序列表。getSorted 用于根据排序方式选择使用哪个排序函数。

在使用选择器函数时,我们可以像下面这样调用它:

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

在上面的代码中,我们传入 state 参数调用 getSorted 函数,并获取排序后的结果。

总结

Reselect 是一个用于创建可记忆的选择器函数的库,可以避免重复计算,提高应用性能。使用 Reselect 需要遵循一些优化原则,包括选择器函数应该是纯函数,选择器函数应该是高效的。在实际使用中,我们可以将复杂计算拆分成多个选择器函数,然后组合起来使用。

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


猜你喜欢

  • TypeScript 开发中 JavaScript 导入模块时的坑点

    TypeScript 是一种由微软开发的开源编程语言,它是 JavaScript 的一个超集,可以编译成纯 JavaScript 代码。在前端开发中,TypeScript 提供了更强大的类型检查和代码...

    8 个月前
  • 剖析 CSS Reset 的本质

    在前端开发中,我们经常会使用 CSS Reset 来统一不同浏览器的默认样式,这样我们可以更好地控制页面的样式。本文将深入剖析 CSS Reset 的本质,包括它的作用、原理以及如何使用。

    8 个月前
  • Deno 中如何使用 WebSocket 进行游戏开发?

    在前端开发中,WebSocket 是一种常用的技术,它可以在浏览器与服务器之间建立一个长久的连接,使得双方可以实时通信。而 Deno 作为一个新兴的后端 JavaScript 运行时,也提供了 Web...

    8 个月前
  • 现代 JavaScript 开发必须掌握的 Webpack 技巧

    Webpack 是一个现代化的 JavaScript 应用程序打包工具,它可以将多个 JavaScript 文件打包成一个或多个文件,使得应用程序的加载速度更快、资源更少。

    8 个月前
  • Angular UI 组件库搭建项目时的注意点

    前言 Angular UI 组件库是 Angular 框架中常用的 UI 组件库之一,它提供了一系列常用的 UI 组件,如按钮、表单、模态框等,可以快速帮助我们构建美观且交互友好的前端界面。

    8 个月前
  • 在 Chai 测试中如何 mock Ajax 请求

    在前端开发过程中,使用 Ajax 请求获取数据是常见的操作。然而,在测试过程中,由于网络环境和服务器的不确定性,我们很难保证每次请求都会返回正确的数据。为了解决这个问题,我们可以使用 mock Aja...

    8 个月前
  • 常见 bug:Custom Elements 实例无法通过 querySelectorAll 获取

    背景 在 Web 开发中,我们经常需要使用 Custom Elements 来扩展 HTML 标签。Custom Elements 允许我们创建自定义的 HTML 元素,并在其中添加自定义行为和样式。

    8 个月前
  • 在微信公众号中使用 Server-Sent Events 实现实时消息推送

    前言 随着互联网技术的发展,实时消息推送已经成为了现代 Web 应用程序中必不可少的一部分。在 Web 开发中,我们通常使用 WebSocket 或者长轮询(Long Polling)来实现实时消息推...

    8 个月前
  • Node.js + Socket.io 实现企业内部 IM 系统

    随着企业规模的不断扩大,内部沟通变得越来越重要。传统的邮件、电话等沟通方式已经不能满足企业的需求。因此,企业内部 IM 系统成为了一种必不可少的工具。 本文将介绍如何使用 Node.js 和 Sock...

    8 个月前
  • 解决 Koa2 中 CORS 跨域问题的方法总结

    前言 在前端开发中,经常会遇到跨域问题,特别是在使用 Koa2 进行服务器端开发时,由于默认情况下 Koa2 不允许跨域请求,因此需要进行一些设置才能解决跨域问题。

    8 个月前
  • 使用 ESLint 检查 Angular 服务代码的最佳实践

    在 Angular 应用程序中,服务是一种常见的代码组织方式。服务提供了一种在不同组件之间共享数据和逻辑的方法。然而,与任何代码一样,服务代码也需要遵循最佳实践来确保可读性、可维护性和可扩展性。

    8 个月前
  • PWA 如何解决 iOS 上无法打开新窗口的问题?

    背景 在 iOS 上,Web 应用程序无法像桌面浏览器那样在新窗口中打开链接。这可能会对一些 Web 应用程序造成困扰,因为它们需要在新窗口中打开链接,例如电子商务网站的商品详情页、社交媒体应用程序的...

    8 个月前
  • 解决 Express.js 错误:Cannot read property ‘toLowerCase’ of undefined

    在使用 Express.js 进行开发时,有时候会遇到 Cannot read property ‘toLowerCase’ of undefined 的错误。这个错误通常是由于在使用 Express...

    8 个月前
  • Angular.js SPA 应用中的前端依赖注入实现

    前言 在 Angular.js 中,依赖注入是一个非常重要的特性。它使得我们可以更灵活、更高效地管理组件之间的依赖关系。在本文中,我们将深入探讨 Angular.js 中的依赖注入实现,并提供一些示例...

    8 个月前
  • Vue.js + axios 如何在请求头中携带 token?

    在前端开发中,我们经常需要向后端发送请求来获取数据,而这些数据往往是需要身份验证的。在这种情况下,我们需要在请求头中携带 token 来进行身份验证。Vue.js 和 axios 是前端开发中常用的工...

    8 个月前
  • ECMAScript 2018 中的 Object.getOwnPropertyDescriptors() 的使用指南

    在 ECMAScript 2018 中,Object.getOwnPropertyDescriptors() 是一个非常有用的方法,它可以返回一个对象的属性描述符。

    8 个月前
  • ES8 中的 Promise.race() 和 Promise.allSettled() 方法

    前言 随着 JavaScript 的发展,Promise 已经成为了现代 JavaScript 开发中最常用的异步编程方式之一。ES8(ECMAScript 2017)中,Promise 引入了两个新...

    8 个月前
  • Mocha 测试中如何处理多个测试套件之间的依赖关系

    在前端开发中,测试是非常重要的一环。而 Mocha 是一个流行的 JavaScript 测试框架,它提供了丰富的功能和灵活的配置选项。但是,在实际的测试过程中,我们可能会遇到多个测试套件之间存在依赖关...

    8 个月前
  • ES6 中新增的 Symbol 类型及其用法

    在 ES6 中,新增了一种基本数据类型 Symbol。Symbol 作为一种全新的数据类型,与其他类型不同,它的值是唯一的,可以用作对象属性的键名。 Symbol 的创建 Symbol 可以通过 Sy...

    8 个月前
  • 使用 ES7 的 Async/Await 解决 JavaScript 代码中的同步问题

    在编写 JavaScript 代码时,经常会遇到异步操作的问题。例如,当我们需要从服务器获取数据或者执行一些耗时的操作时,我们会使用回调函数或者 Promise 对象来处理异步操作。

    8 个月前

相关推荐

    暂无文章