useSelector 解构与多次调用

2024-04-27

最近我在阅读react-redux 文档https://react-redux.js.org/next/api/hooks https://react-redux.js.org/next/api/hooks还有一个与平等比较和更新相关的部分,其中写道:

多次调用 useSelector(),每次调用返回一个字段值。

第一种方法:

const { open, importId, importProgress } = useSelector((importApp) => importApp.productsImport);

第二种方法:

const open = useSelector((importApp) => importApp.productsImport.open);
const importId = useSelector((importApp) => importApp.productsImport.importId );
const importProgress = useSelector((importApp) => importApp.productsImport.importProgress);

那么有什么真正的区别吗?或者由于解构 useSelector 钩子在检查引用时会遇到麻烦?


只是为了奠定基础:在分派操作时,您传递给的选择器useSelector()将被调用。如果它返回的值与上次调度操作时返回的值不同,则组件将重新渲染。

破坏确实是错误的方法,但这里的最佳答案完全无关。文档提到了一种场景,其中选择器每次都创建一个新对象,就像您在mapStateToProps()功能。这将导致组件在每次分派操作时重新渲染,无论该操作执行什么操作,因为从技术上讲,选择器返回的值是内存中的不同对象,即使实际数据没有更改。在这种情况下,您需要担心严格相等和浅层相等比较。然而,你的选择器并不是每次都创建一个新对象。如果分派的操作没有修改importApp.productsImport,它将是内存中与以前完全相同的对象,从而使所有这些都变得毫无意义。

相反,这里的问题是,当您实际上只关心该切片的一些特定属性时,您正在选择整个状态切片。考虑一下importApp.productsImport除了以下属性之外,可能还具有其他属性open, importId, and importProgress。如果这些其他属性发生变化,那么您的组件将不必要地重新渲染,即使它没有引用它们。原因很简单:选择器返回importApp.productsImport,并且该对象发生了变化。 Redux 无法知道这一点open, importId, and importProgress是您真正关心的唯一属性,因为您没有选择这些属性;您选择了整个对象.

解决方案

因此,要选择多个属性而无需重新渲染,您有两种选择:

  • 使用多个useSelector()钩子,每个钩子选择商店中的一个属性。
  • Have a single useSelector() hook and a single selector that combines multiple properties from your store into a single object. You could do this by:
    • 使用记忆选择器reselect https://github.com/reduxjs/reselect.
    • 只需编写一个函数,根据特定属性创建一个新对象state并返回它。如果你这样做,你会then必须担心严格的平等和浅薄的平等比较。

为了这个目的,我想多useSelector()hooks 实际上是要走的路。该文档特别提到

每次调用 useSelector() 都会创建对 Redux 存储的单独订阅。

但我认为,与纯粹出于这个原因的单个调用相比,多个调用实际上是否会真正带来真正的性能损失,还有待观察,而且在我看来,担心这一点可能是过度优化,除非你有一个巨大的应用程序数百或数千个订阅。如果您使用单个useSelector()钩子,那么此时你基本上只是在写一个mapStateToProps函数,我觉得它削弱了使用钩子的很多吸引力,特别是如果你正在编写 TypeScript。如果你then想要解构结果,这使得它变得更加麻烦。我还认为使用多个钩子绝对更符合 Hooks API 的一般精神。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

useSelector 解构与多次调用 的相关文章

随机推荐

  • Python 元类有什么用?

    元类可以用其他方式做不到的事情做什么 Alex Martelli 表示 有些任务如果没有元类就无法完成Python 元类与类装饰器 https stackoverflow com questions 1779372 python metac
  • Openfire 在用户离线时发送推送通知

    我使用 openfire 3 9 3 服务器和 Android 和 IOS 作为客户端 我想在收件人用户离线时通过推送通知向两个客户端发送消息 当发送推送时 发送者应该收到消息收据 为此 我尝试过 制作拦截器 在此 我没有收到任何可以跟踪的
  • R rvest 检索空表

    我正在尝试两种策略来从网络表中获取数据 library tidyverse library rvest webpage lt read html https markets cboe com us equities market stati
  • 在iOS中,在纯C中,这是获取本地文件路径的方法吗?

    我需要最终得到一个 cstring 作为捆绑包中文件的本地路径 First include
  • Laravel updateOrCreate 带有自动增量数据库

    我的目的是如果值存在则更新 否则插入新行提交表单后在数据库表中 问题是 这里的函数添加新列在数据库表中而不是更新它们 这是我的功能 MyModel updateOrCreate array myField gt myValue gt whe
  • 如何同时将单个卷挂载到多个/var/lib/docker?

    可以将单个 docker 卷共享给多个 docker 容器 var lib docker目的地 一个最小的可重现示例如下 docker volume create name lib docker run privileged v lib v
  • Primefaces 问题:使用 ViewScoped 托管 bean 从 p:datatable 进行 p:filedownload

    使用 ViewScoped 托管 bean 从 p datatable 进行 p filedownload 不起作用 它调用方法prepareFile和getFile两次 在我提到的方法的第一次调用中 它设置表中的第一个文件 在方法的第二次
  • ZipInputStream.getNextEntry() 如何工作?

    假设我们有这样的代码 File file new File zip1 zip ZipInputStream zis new ZipInputStream new FileInputStream file 假设您有一个包含以下内容的 zip
  • 如何检查 Google 地图是否已完全加载?

    我正在将 Google 地图嵌入到我的网站中 加载 Google 地图后 我需要启动一些 JavaScript 进程 有没有办法自动检测 Google 地图何时完全加载 包括图块下载等 A tilesloaded 存在应该完全完成此任务的方
  • 使用 CURL post 方法的 Google 翻译 API

    有人有过使用 Google 翻译 API v2 在 POST 方法上使用 PHP CURL 翻译 HTML 的经验吗 我已经尝试了 github 上的几个代码和库 但没有一个适合我 我发现的是 GET 方法 由于通过 GET 或查询字符串解
  • 在测试中检查 CLI 的退出代码

    我正在为命令行工具编写自动化测试 本质上 我想使用各种选项调用 CLI 并测试退出代码和 或输出 我的测试如下所示 from mymodule cli tool import main def test args capfd with py
  • Heroku 缺少必需的标志:-a,

    我目前正在做一个项目 但我在使用 Heroku 时遇到了问题 这是当我尝试使用 heroku 命令时总是出现的错误 问题中的错误 https i stack imgur com bEQ0m png 请问有同样错误的朋友 可能是什么原因造成的
  • Golang xml.Unmarshal 接口类型

    使用xml我在解组非同质类型列表时遇到问题 考虑以下 XML 文档 其嵌套元素是非同质类型的列表
  • py2exe + sqlalchemy + sqlite 问题

    在进入全速开发模式之前 我正在尝试让一些基本的东西在 Python 中工作 具体如下 Python 2 5 4 PyQt4 4 4 3 SqlAlchemy 0 5 2 py2exe 0 6 9 setuptools 0 6c9 pysql
  • String 对象上的“tap”方法未返回预期结果

    在对 String 类型的对象使用 tap 方法时 我遇到了一个有趣的问题 abc tap o o xyz this line returns abc instead of xyz tap 方法适用于其他类型的对象 tap o o lt l
  • 将自定义路由添加到 Rails 应用程序

    我已经读过导轨指南 http guides rubyonrails org routing html 我想要设置的是路由到 配置文件 控制器的以下路由 GET profiles charities 应显示所有慈善机构 GET profile
  • 在 SQL 中查找日期范围重叠的记录

    我有以下表格和数据 CREATE TABLE customer wer id customer NUMBER name VARCHAR2 10 surname VARCHAR2 20 date from DATE date to DATE
  • 验证 PDF 文档中的数字签名

    我正在尝试验证 PDF 数字签名 我知道 当 PDF 被签名时 会定义一个字节范围 嵌入证书 并且根据我的阅读 签名的消息摘要和时间戳也存储在 PDF 中 我已经可以提取证书并验证它们 现在我正在尝试验证 pdf 的完整性 但我的问题是我不
  • 从该共享库中查找加载的共享库的位置?

    从共享库中的函数 在正在运行的进程 用 C 编写 内 我如何发现该共享库是从哪里加载的 我找到的所有答案都涉及使用诸如ldd在命令行中 或者通过查看 proc self maps 在 Win32 上 我只需使用GetModuleFileNa
  • useSelector 解构与多次调用

    最近我在阅读react redux 文档https react redux js org next api hooks https react redux js org next api hooks还有一个与平等比较和更新相关的部分 其中写