React redux connect渲染优化

时间:2019-06-18 10:34:01

标签: javascript reactjs redux

我试图通过限制内容未更改的组件的渲染调用次数来了解如何在React中管理复杂状态。

例如:

我已使用“ items”道具(即数组)简单地连接到redux存储容器组件。

const Component = ({ items }) => (
    <>{items.map(item => <ItemComponent key={item.id} {...item} />}</>
);

const mapStateToProps = state => ({
    items: $$data.select.items(state),
});

const ConnectedComponent = connect(mapStateToProps)(MyComponent);

每次复杂存储的任何部分发生更改时-即使项数据没有更新,即使项数据为空,项属性也会更改:oldProp:[] => newProp:[]。并导致重新渲染。 (我在React Dev Tools中找到了它,它突出显示了更新的组件)

我应该担心这种不必要的退货吗?最好的解决方法是什么? 我已经发现新的React.memo hoc可以停止重新渲染,但这是个好方法吗?

5 个答案:

答案 0 :(得分:5)

mapStateToProps调用中使用connect()意味着您希望在商店更改时通知您的组件-无论您感兴趣的小片段是否已更改,都会发生这种情况除此之外,react-redux通过对mapStateToProps返回的对象和先前的道具进行浅表比较来防止不必要的重新渲染。

以您的示例为例,每次newProp: []这样的场景都会创建一个新数组,因此,由于数组是不同的实例,因此无法进行较浅的比较。

  

我应该担心这种不必要的放弃吗?

React注意不要不必要地重新渲染组件,因此,即使再次调用render,只要对组件的props并未实际更改,React也不会做任何其他操作工作。可以肯定地说,对于大多数应用程序而言,不必要的重新渲染并不是所有问题。

如果您认为它会影响您的应用程序,或者您只是想了解更多有关减少它的方法,那么关于性能的材料很多:

答案 1 :(得分:4)

减速器很可能有问题。否则,您可以使用reselect库来定义用于记忆值的选择器,这样除非值真正更改,否则不会重新渲染。

答案 2 :(得分:3)

将您的组件与商店连接意味着“在更改道具时调用我的组件或组件的渲染方法”。默认比较是通过简单的相等性检查进行的,这在您的数据中可能为假。

因此,在您的应用程序中,即使没有必要,也很有可能创建了新的对象或数组。这是您遇到的第一个更大的问题。

即使您的组件需要重新渲染,它也会执行render方法,但是您的影子dom仍然是相同的,因此在大多数情况下,您无需进行任何昂贵的操作。

您可以执行以下步骤:
 -不要创建不必要的新对象和数组引用。好吧,这是正确且更长的解决方案
 -使用mapStateToProps实现自己的相等性检查。有很多优化选择器逻辑的方法,但这取决于应用程序的详细信息。最好在此处关注此帖子:https://medium.com/practo-engineering/avoiding-re-renders-in-react-and-optimising-mapstatetoprops-with-reselect-6e199fa7bc73

  

我应该担心这种不必要的放弃吗?

这实际上取决于您的应用程序的大小。您可能应该有一些基准测试,并检查一些反应性能工具。

答案 3 :(得分:1)

您可以使用组件生命周期方法shouldComponentUpdate,该方法将通过nextStatenextProps传递。这样,您可以通过返回true(更新)或false(不更新)来决定组件是否需要更新。

文档:here

答案 4 :(得分:0)

如果您使用的是react-redux> = 6.0.0,则React DevTools中有一个错误,会错误地显示突出显示的重新渲染。

带有“重点更新”的误报
https://github.com/facebook/react-devtools/issues/1290

这里发生的是包装的组件将被重新渲染,而不是您正在使用connect的组件。