调试React Context重新渲染

3

我正在尝试优化我的React应用程序以删除不必要的渲染。

请参考此Snack示例:https://snack.expo.io/bUZpyw0kH

在这个示例应用程序中,有两个存储在上下文中的状态变量。其中一个值每秒更新一次,另一个永远不会改变。

我尝试理解的是为什么每秒都会调用console.log('rerender');

据我所知,当您解构存储在上下文中的变量时,只有在解构的变量更改时才会收到更新。我只访问otherValue,而不是每秒都更改的elapsed。在这种情况下,为什么会出现console.log('rerender')

在这种情况下,console.log('context child render'); 不是每次都被调用,因为我已经使用 React.memo 包装了这个组件。

我应该更改这个还是将ContextChild包装在React.memo中就足够高效了?我需要拆分成多个提供者吗?如果需要拆分,组件如何访问两个上下文的变量?

2个回答

4
据我理解,当您在上下文中解构存储的变量时,只有在解构变量发生更改时才会接收到更新。
不幸的是,React无法确定从上下文中读取的值是否已被解构。上下文提供单个值,React仅知道组件正在消耗提供程序中的值。提供者的使用者将在值更改时重新呈现。
在此示例中,单个值由2个状态值和一个状态设置器组成。其中一个值经常更改,导致状态更新,然后重新呈现提供程序。渲染创建一个新对象并将其设置为提供程序的值(value = {{elapsed,otherValue,setOtherValue}} 是一个新对象)。然后检查此新对象与上一个值是否相同,以确定是否需要更新使用者。因为两个值不能相同( {}!== {} === true ),每个使用者都会进行更新。
---
“我应该更改此内容还是将ContextChild包装在React.memo中是否足够高效?”
这是主观的,需要针对每个应用程序进行思考。
是否需要优化?
仅读取 otherValue 的使用者的更新是否昂贵?如果更新很便宜,并且没有很多更新,则不需要优化。如果更新明显,并且在滚动或与页面交互时导致延迟,则可能需要优化。
应该进行哪些优化?
大多数使用者是否都需要这两个值,还是大多数只读取其中一个值?如果大多数组件仅使用对象中的一个值,则将上下文拆分为两个单独的提供程序以满足这两个单独的用例可能是有意义的。但是,如果只有少数使用者关心其中一个值而不是两个值,则 React.memo 解决方案可能足以处理这些情况,而无需使其他使用者受到代码膨胀以从多个上下文中读取。

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接