Redux 选择器是否会导致不必要的组件渲染?

Ade*_* MR 5 selector redux

根据我从 Dan Abramov 的蛋头视频“javascript-redux-co located-selectors-with-reducers”和他的一些推文中了解到的,使用选择器将状态映射到 prop 并删除此逻辑是一个很好的做法从 Component 中获取并将其放置在Reducer 中(管理状态的地方)。

尽管这很有意义,但它也会导致每次将新状态添加到存储中时我的组件都会进行渲染,即使仅更改状态对象的非相关属性也是如此。有没有一种方法可以在不使用重选器的情况下克服这个问题,这对于更简单的情况可能有点过大?

nic*_*oqh 3

如您所知,mapStateToProps每次更新您的商店时都会调用它。

\n\n

组件是否会重新渲染取决于mapStateToProps返回的内容。(实际上,这取决于mapStateToProps mapDispatchToProps返回的组合 props 对象。)

\n\n

React Redux(提供该功能的库)对返回的对象和最后connect返回的对象进行浅层相等检查。如果相等性检查成功(即先前返回的对象被确定为等于下一个返回的对象),则组件将不会重新渲染。如果检查失败,组件将重新渲染。

\n\n

例如,假设您始终从 返回以下对象mapStateToProps

\n\n
{\n  items: [],\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

该对象永远不会等于其自身([] === []返回,false因为它们是不同的数组)。因此,相等性检查将失败,并且组件将重新渲染。

\n\n

然而,React Redux 执行了更复杂的相等检查(其函数的实现可以在这里shallowEqual找到)。

\n\n

例如,即使{ a: \'b\' } === {\xc2\xa0a: \'b\'}返回false(它们是不同的对象),shallowEqual 也会将它们视为相等。这是因为shallowEqual会将返回对象的每个键与先前返回对象的每个键进行比较,但只进行一层深度比较。更多细节可以在我上面链接的实现中找到。

\n\n

总之,如果您不希望组件重新渲染,则需要确保相等检查成功。

\n\n

你可以:

\n\n
    \n
  • 使用reducer将返回的对象保存到state中
  • \n
  • 使用重新选择缓存结果
  • \n
  • shouldComponentUpdate手动在组件中实现
  • \n
\n\n

这些建议直接来自 Redux 的常见问题解答页面:https://redux.js.org/docs/faq/ReactRedux.html#react-rendering-too-often

\n\n

您还可以确保您的mapStateToProps函数返回被认为等于的对象shallowEqual(例如,没有数组的对象,并且只有一层深)。

\n\n

为简单起见,我会选择重新选择。

\n