redux React Native - React Navigation在嵌套导航器时转换缓慢

t98cgbkg  于 2023-04-12  发布在  React
关注(0)|答案(8)|浏览(178)

我正在使用react-native构建一个跨平台的原生应用程序,并使用react-navigation来导航到屏幕和从屏幕导航,并使用redux管理导航状态。
例如,我使用堆栈导航器作为我的应用程序的默认导航器。

export const DefaultNavigate = new StackNavigator(
{
        Login: {
            screen: LoginScreen,
        },
        Home: {
            screen: AppDrawerNavigate,
        },
        AppTabNav: {
            screen: AppTabNavigator,
        },
    }
);

我的第一个屏幕是登录屏幕,主屏幕是抽屉导航器。

const AppDrawerNavigate = new DrawerNavigator(
{
        InProcess: {
             screen: InProcess,
        },
        Machine: {
             screen: Machine
        },
        Settings: {
             screen: Settings
        },
        Logout: {
             screen: Logout
        },
        ContactUs: {
             screen: ContactUs
        }
    }
);

当用户单击抽屉导航器中的机器时,我将屏幕导航到DefaultNavigator中声明的AppTabNav。

const AppTabNavigator = new TabNavigator(
    {
        MachineList: {
            screen: MachineList,
        },
        CalendarView: {
            screen: CalendarView,
        }
    },
);

这是一个标签导航器,顾名思义有两个屏幕,一个是使用listview显示列表,另一个是使用calendarview显示日历。在我的listview的dataSource中只有大约30-40个项目,所以渲染它们对于listview来说是小菜一碟。但是当从DrawerNavigator从任何屏幕导航到Machine屏幕时,会有1- 2秒的滞后,js线程下降到-2。1,这实际上减慢了转换速度.

如果有人需要抽屉导航器中机器屏幕的代码,在这里,

componentDidMount() {
    if(this.state.loaded)
        this.props.navigation.dispatch({ type: MACHINE});
}
render() {
    return <AppActivityIndicator />
}

下面是我的reducer代码,它处理屏幕的导航,

case types.MACHINE:
  nextState = DefaultNavigate.router.getStateForAction(
    NavigationActions.reset({
      index: 1,
      actions: [
        NavigationActions.navigate({ routeName: 'Home' }),
        NavigationActions.navigate({ routeName: 'AppTabNav' })
      ]
    }),
    state
  );

以下是抽屉式导航器中MachineList屏幕的呈现方法,

render() {
    return (
        <View style={styles.container}>
            <AppStatusBar />
            <ListView
                initialListSize={10}
                dataSource={this.state.dataSource}
                renderRow={this.renderRow.bind(this)}
                enableEmptySections={true}
            />
        </View>
    );
}

请帮我一把我做错了什么
从属关系

"dependencies": {
    "native-base": "^2.3.1",
    "react": "16.0.0-alpha.12",
    "react-devtools": "^2.5.0",
    "react-native": "0.47.1",
    "react-native-calendars": "^1.5.8",
    "react-native-vector-icons": "^4.3.0",
    "react-navigation": "^1.0.0-beta.11",
    "react-redux": "^5.0.6",
    "redux": "^3.7.2",
    "redux-logger": "^3.0.6",
    "redux-persist": "^4.9.1",
    "redux-thunk": "^2.2.0"
},
"devDependencies": {
    "babel-jest": "20.0.3",
    "babel-preset-react-native": "3.0.0",
    "jest": "20.0.4",
    "react-test-renderer": "16.0.0-alpha.12"
},
bttbmeg0

bttbmeg01#

我也面临着同样的问题。切换屏幕时有很大的延迟。我发现这个非常有用的博客https://novemberfive.co/blog/react-performance-navigation-animations/
所以问题是
当推送一个新屏幕时,React Navigation最初会在屏幕外渲染它,然后将其动画化。这意味着当推送一个包含大量组件的复杂屏幕时,很容易需要几百毫秒来渲染。
为了解决这个问题,我使用了InteractionManager。它基本上会在所有动画完成后给你一个回调。
以下是我所做的,以避免延迟和应用程序是工作正常后,修复.希望这有帮助.

// @flow

import React, { Component } from 'react';
import { InteractionManager, ActivityIndicator} from 'react-native';

class Team extends Component<Props> {
 state = {
    isReady : false
 }
 componentDidMount() {
   // 1: Component is mounted off-screen
   InteractionManager.runAfterInteractions(() => {
     // 2: Component is done animating
     // 3: Start fetching the team / or render the view
    // this.props.dispatchTeamFetchStart();
     this.setState({
       isReady: true
     })
   });
 }

 // Render
 render() {
  if(!this.state.isReady){
  return <ActivityIndicator />
  }
  return(
   //  Render the complex views
   )
   ...
 }
}

export default Team;
1sbrub3j

1sbrub3j2#

我在我的应用程序中遇到了同样的问题。与其他人描述的类似,我嵌套了堆栈和抽屉导航器。对我来说,滞后是嵌套堆栈导航器中屏幕之间的转换。
我尝试使用InteractionManager来解决这个问题,但似乎没有太大的区别。最终我发现,在中构建一个简单的超时来延迟大型组件的渲染会产生巨大的差异。
所以,我写了这个简单的useIsReady钩子,我现在在我的屏幕上使用:

import { useEffect, useState } from "react";

const useIsReady = () => {
  const [isReady, setIsReady] = useState(false);

  useEffect(() => {
    setTimeout(() => setIsReady(true), 100);
  }, []);

  return isReady;
};

export default useIsReady;

这是我在屏幕中使用钩子的方式:

import React, { memo } from "react";
import { useTheme } from "react-native-paper";
import { View, ActivityIndicator } from "react-native";
import { useIsReady } from "hooks";

const BusyIndicator = () => {
  const theme = useTheme();
  return (
    <View style={{ flex: 1, justifyContent: "center" }}>
      <ActivityIndicator size="large" color={theme.colors.primary} />
    </View>
  );
};

const Camera = () => {
  const isReady = useIsReady();

  if (!isReady ) {
    return <BusyIndicator />;
  }
  
  return (
    <> ... </>
  );
};

export default memo(Camera);

我发现这让世界变得不同了,我的屏幕过渡现在完全流畅了。

x7yiwoj4

x7yiwoj43#

我也遇到了同样的问题,对我来说,它帮助使用NativeStackNavigator而不是StackNavigator

gzszwxb4

gzszwxb44#

我也面临着同样的问题。以下步骤帮助我大大减少了滞后时间:
1.如果你用redux的compose Package 了你的组件(尤其是BottomTabBar中的组件),你会很好地删除它。这将大大提高过渡的平滑度和速度。
1.正如@卡洛斯在上面强调的那样,使用InteractionManager.runAfterInteractions(()=>{})

vpfxa7rd

vpfxa7rd5#

将回调函数传递给预定义的requestAnimationFrame(无需导入)方法,一旦动画完成,它将自动调用该函数。

requestAnimationFrame(() => {
   navigation.navigate('routeName') //enter code here
}
yacmzcpb

yacmzcpb6#

Optimize memory usage and performance (v5)
对于那些使用react导航版本5的用户
您需要首先按照react-native-screens的安装说明进行安装。然后在渲染导航堆栈之前使用以下代码片段(通常在index.js或App.js文件中):

// Before rendering any navigation stack
import { enableScreens } from 'react-native-screens';
enableScreens();
cx6n0qe3

cx6n0qe37#

我正面临着缓慢的标签导航问题,缓慢的问题发生时,有嵌套的东西,如在我的情况

  • 我有抽屉从react-navigation/drawer第一级
  • 第二,我有标签从'@react-navigation/bottom-tabs'下的抽屉第二级别

第三件事我有一个堆栈(它有多个屏幕)从@react-navigation/堆栈下的标签第三级

<Drawer.Navigator>
  <Tab.Navigator>
    <Stack.Navigator>
      <Stack.Screen name="Home"></Stack.Screen>
      <Stack.Screen name="Details"></Stack.Screen>
    </Stack.Navigator>
     <Stack.Navigator>
       <Stack.Screen name="Task"></Stack.Screen>
       <Stack.Screen name="Details"></Stack.Screen>
     </Stack.Navigator>
     .....
  </Tab.Navigator>
</Drawer.Navigator>

因此,如果我删除上面的任何一个东西,缓慢的问题就消失了,例如,如果我删除Drawer.Navigator,所以我只有两个嵌套的东西,Tab.Navigator和Stack.Navigator,所以问题就消失了。
所以我删除了Drawer并使用了一个来自native base的drawer(你可以使用另一个drawer包)。

<Tab.Navigator>
       <Stack.Navigator>
           <Stack.Screen name="Home"></Stack.Screen>
           <Stack.Screen name="Details"></Stack.Screen>
       </Stack.Navigator>
      <Stack.Navigator>
           <Stack.Screen name="Task"></Stack.Screen>
           <Stack.Screen name="Details"></Stack.Screen>
       </Stack.Navigator>
       .....
   </Tab.Navigator>

我知道有多痛苦,我忍受了很长一段时间,没有找到任何解决方案,从官方React导航团队,希望团队将修复嵌套问题很快,现在,你可以使用该解决方案。

hwazgwia

hwazgwia8#

我也面临着这个问题与堆栈导航器,抽屉导航器工作得更好..在堆栈中,如果有超过100行的内容与一些进口的组件,它开始的滞后和延迟导航。
我在我的一个堆栈屏幕中使用InteractionManager来渲染动画后的组件
它的工作,但当我回来点击返回,动画快门/滞后
我检查了https://reactnavigation.org/docs/react-native-screens/
因为它说react-navigation已经使用了本机导航组件
禁用和使用RN View:-

import {enableScreens} from 'react-native-screens'
enableScreens(false)

我禁用了它,现在它的工作方式比本机更好,不知道为什么,目前我在调试模式,所以不能说,如果它的原因是远程视图…
真的很困惑,为什么它滞后于本地导航,而不是在RN视图可以有人让我知道为什么它的发生?我想使用本地导航

相关问题