【问题标题】:React Native app so slow when components are nested in each other当组件相互嵌套时,React Native 应用程序非常慢
【发布时间】:2021-12-29 19:31:59
【问题描述】:

当我尝试实现以下结构时,出现了我的问题。 主屏幕将是底部标签,并且应用程序有更多的全屏覆盖,为简单起见,它只会在 TabOne 中使用。

所以我的标签的结构是这样的:

<Tab.Navigator
        initialRouteName={MenuType.TAB_ONE}
        screenOptions={{ headerShown: false }}
        style={{ flex: 1 }}
        tabBar={(props) => <BottomTabs {...props} />}
      >
        <Tab.Screen
          name={MenuType.TAB_ONE}
          component={TabOne}
        />
        <Tab.Screen
          name={MenuType.TAB_TWO}
          component={TabTwo}
        />
        <Tab.Screen
          name={MenuType.TAB_THREE}
          component={TabThree}
        />
      </Tab.Navigator>

&lt;BottomTabs {...props} /&gt; 是我自己的自定义底部标签 UI。 如果我将所有MyOverlay 组件放在TabOne 中,那么它就不会覆盖底部标签。

如果我将它们与我的主应用程序中的Tab.Navigator 放在同一级别,它将按我的预期工作,我们称之为MainApp

<Tab.Navigator .....>
<MyOverlay />

但由于它们位于不同的组件上。我用useContext互相交流。

例如,当 TabOne 页面中的一个按钮被按下时,我将调用上下文方法到setFlag()openBottomSheet 标志,然后我将useContext 监听openBottomSheet 标志在我的MainApp .

但是随着状态的变化,MainApp 只是重新渲染所有内容。这意味着它会重新呈现我的自定义BottomTabs、所有TabOneTabTwoTabThree,并且在每个标签页中,都有许多子组件。当更多组件添加到视图中时,我的应用程序变得越来越慢。 (我无法想象如果有一个状态(位于MainApp,因为我的对话框位于位于那里的叠加层中)跟踪对话框内的变化,然后我的应用程序就像在每个输入上“重新启动”一样会发生什么我在对话框中输入...)

我觉得每次状态变化时我都会再次运行整个应用程序。

我尝试将React.memo 用于一些稳定的组件,例如BottomTabs,但没有运气,因为我的所有组件都有自己的状态、上下文,...正如此处所述https://reactjs.org/docs/react-api.html#reactmemo

我试图让我的组件成为一个扩展 React.Component 的类,但是我的 useContext 无法在 React.Component 中工作

我不知道我对 Hooks 的使用有什么问题...

感谢您的宝贵时间。

更新: 一个可重现的示例 repo https://github.com/tranhoainam/test-tabs-and-sheet 每次单击按钮(显示工作表或显示/隐藏对话框)时,我都会得到这些日志:

>>> RENDER MAIN APP
>>>->>> RENDER one
>>>->>> RENDER two
>>>->>> RENDER three
   -->>> RENDER OVERLAY

由于组件非常复杂,我的应用程序变慢了

更新 2 我的第一个猜测是,因为我的应用程序当前包装在 &lt;MainProvider&gt; 中,所以一旦该提供的状态的每个部分发生变化,RN 将重新呈现该提供者的整个孩子。

所以我想出了一个解决方案,即为覆盖创建另一个 Provider,称为 OverlayProvider

  • 然后我将&lt;Overlays/&gt; 包裹在&lt;OverlayProvider&gt;
  • 然后我必须用我的新&lt;OverlayProvider&gt; 包裹调用工作表的按钮,否则会出现错误,提示我的openBottomSheet 方法未定义。

这时又出现了另一个问题。因为有两个&lt;OverlayProvider&gt;,所以看起来它们是两个不同的实例,所以当openBottomSheet 被调用时。 &lt;Overlays/&gt; 中的标志不会改变。

有没有办法让这两个提供者成为一个实例?

请在此处查看我的解决方案分支以了解想法https://github.com/tranhoainam/test-tabs-and-sheet/tree/another-solution

【问题讨论】:

  • 您能否更新您的问题以包含您遇到问题的所有相关代码?见minimal, complete, and reproducible code example。如果可能,您能否为您的代码创建一个running Expo snack 来重现我们可以实时检查和调试的问题?
  • 嗨@DrewReese 请检查底部的更新回购,看看您是否可以更好地猜测发生了什么。谢谢

标签: javascript react-native react-hooks


【解决方案1】:

我最终在我的案例中使用了 Redux。上下文不适合我的情况。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-06-05
    • 1970-01-01
    • 2012-10-12
    • 2020-04-09
    • 2017-04-27
    • 1970-01-01
    • 2019-12-05
    相关资源
    最近更新 更多