最近我在阅读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(使用前将#替换为@)