【问题标题】:React navigation v5 slow because rerenders current screen before opening drawer反应导航 v5 很慢,因为在打开抽屉之前重新渲染当前屏幕
【发布时间】:2021-05-12 08:49:45
【问题描述】:

我正在开发一个更大的应用程序,打开抽屉时有些延迟。抽屉动画开始大约需要 1 秒
我使用 react profiler 对其进行了查看,发现 抽屉已被渲染,并且当前屏幕在抽屉打开之前被重新渲染。这让事情感觉很慢,我不会怀疑当前屏幕要重新渲染。
这是我的 pseudo 导航堆栈自上而下的样子:

//Toplevel
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';

const RootStack = createStackNavigator();
<NavigationContainer ref={navRef} theme={navTheme} linking={linking}>
  <RootStack.Navigator>
    {loggedIn ? (
      <RootStack.Screen component={inBetweenComponent} /> // => calls drawer
    ) : (
      // auth screen
    )}
  </RootStack.Navigator>
</NavigationContainer>
const DrawerNavigator = () => {
  const Drawer = createDrawerNavigator();
  const route = useRoute();
  const activeRoute = getFocusedRouteNameFromRoute(route);

  return (
    <Drawer.Navigator
      drawerContent={props => <DrawerContent {...props} activeRoute={activeRoute} />}
    >
      <Drawer.Screen name="Notifications" component={NotificationsNavigator} />
      <Drawer.Screen name="Conversations" component={ConversationsNavigator} />
    </Drawer.Navigator>

}
const DrawerContent = ({ activeRoute }) => {
  const navigation = useNavigation();
  return (
    <DrawerContentScrollView>
      <TouchableNative onPress={goToNotifications} >..some text...</TouchableNative>
      <TouchableNative onPress={goToConversations} >..some text...</TouchableNative>
    </DrawerContentScrollView>
  )
}
const NotificationsNavigator = ({ navigation }) => {
  const Stack = createStackNavigator();
  return (
    <Stack.Navigator
      screenOptions={{
        headerLeft: () => <HeaderLeft navigation={navigation} />, // -> contains open drawer button
      }}
      initialRouteName="Notifications"
    >
      <Stack.Screen
        name="Notifications"
        component={NotificationsScreen}
      />
    </Stack.Navigator>
  );
}
const HeaderLeft = () => {
  const navigation = useNavigation();

  const openNavigation = () => {
    navigation.openDrawer();
  };

  <TouchableNative /*someicon*/ onPress={openNavigator} />

我想知道:

  1. 当前活动屏幕在抽屉打开之前重新渲染是否正常?
  2. 如果正常,有没有办法重新渲染当前活动屏幕?我尝试了使用从父级发送的带有 isDrawerOpen (useIsDrawerOpen) 的 useMemo + areEqual 函数的解决方案。但这并不一致,并且经常给出错误或未定义的值。
  3. 非常感谢任何其他说明此堆栈可能变慢的原因。

提前致谢!

【问题讨论】:

    标签: react-native react-navigation react-navigation-drawer


    【解决方案1】:

    打开抽屉时屏幕重新渲染的原因是因为您在 DrawerNavigator 组件中定义了抽屉。

    这意味着每次 React Navigation 想要找到抽屉时,不仅要重新加载当前屏幕,而且抽屉中的每个屏幕都需要重新加载

    const Drawer = createDrawerNavigator(); 移出 DrawerNavigator 应该可以解决您的问题。

    【讨论】:

    • 这绝对是我的错误,我在抽屉和每个堆栈导航器中都犯了这个错误。所以我退出了到处修复它。可悲的是,结果保持不变。打开抽屉时当前屏幕重新渲染.. :/
    • 最后,我在代码示例中调用 InBetweenComponent 的缓存层有一个 useEffect (几乎)每次点击都会触发。这和你的答案在我的设置中都是错误的。感谢您的帮助,我的应用程序现在非常流畅。
    猜你喜欢
    • 2019-08-09
    • 2020-08-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-18
    • 2021-11-22
    相关资源
    最近更新 更多