React Native - 嵌套导航器

时间:2017-09-09 06:18:28

标签: react-native redux react-navigation

我正在使用react-native构建一个跨平台的本机应用程序,并使用react-navigation导航进出屏幕并使用redux管理导航状态。当我筑巢导航器时会出现问题。

例如,我使用Stack Navigator作为我的应用程序的默认导航器。

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
        }
    }
);

当用户在Drawer Navigator中单击Machine时,我将屏幕导航到DefaultNavigator中声明的AppTabNav。

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

这是一个带有两个屏幕的标签导航器,顾名思义,一个是使用listview显示列表,另一个是使用calendarview显示日历。我的listview数据源中只有大约30-40个项目,所以渲染它们对于listview来说是小菜一碟。但是当从DrawerNavigator从任何屏幕导航到机器屏幕时,存在1-2秒的延迟,并且js线程下降到-2.1,这实际上减缓了转换。This drop is frequent whenever I am nesting tab navigator within drawer navigator

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

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

以下是我的减速机代码,它处理屏幕导航,

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>
    );
}

请帮我解决这个问题。我做错了什么?

dependemcies

"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"
},

7 个答案:

答案 0 :(得分:2)

我遇到了同样的问题。切换屏幕时有很长的延迟。我发现这个非常有用的博客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;

答案 1 :(得分:0)

我遇到了选项卡导航缓慢的问题,当像我这样的情况嵌套东西时,就会出现缓慢的问题

  • 我在react-navigation /抽屉中有抽屉第一级

  • 第二,我在抽屉下的“ @ react-navigation / bottom-tabs”中有标签 SECOND LEVEL

我从@ react-navigation / stack中的选项卡第三级

中获得了第三件东西(它有多个屏幕)
<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并从本地库中使用了一个抽屉(可以使用另一个抽屉包)。

   <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>

我知道我遭受了很长时间的痛苦,并且没有从官方的反应导航团队那里找到任何解决方案,希望团队会尽快解决嵌套问题,现在,您可以使用该解决方案。

答案 2 :(得分:0)

我面临着同样的问题。以下步骤帮助我大大减少了延迟时间:

  1. 如果使用定义了屏幕的redux compose包装组件(尤其是BottomTabBar中的组件),则可以很好地删除它。这将大大提高过渡的平滑度和速度。

  2. 就像@Carlos上面突出显示的那样,请使用InteractionManager.runAfterInteractions(()=>{})

答案 3 :(得分:0)

Optimize memory usage and performance (v5)

对于使用第5版反应导航的人

您首先需要遵循react-native-screens中的安装说明。之后,在呈现导航堆栈之前(通常在index.js或App.js文件中)使用以下代码段:

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

答案 4 :(得分:0)

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

requestAnimationFrame(() => {
    //enter code here
}

答案 5 :(得分:0)

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

答案 6 :(得分:-1)

我也面临堆栈导航器的这个问题,抽屉导航器效果更好.. 在堆栈中,如果某些导入组件的内容超过 100 行,则导航开始滞后和延迟。

我在我的一个堆栈屏幕 InteractionManager 中使用它在动画后呈现组件

它有效,但是当我点击返回时,动画百叶窗/滞后

我签了https://reactnavigation.org/docs/react-native-screens/

正如它所说的,react-navigation 已经使用了原生导航组件

用于禁用和使用 RN View :-

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

我禁用了它,现在它的工作方式比原生的好,不知道为什么,目前我处于调试模式,所以不能说这是否是远程视图的原因...

并且真的很困惑为什么它在本地导航上滞后而不在 RN View 中 谁能让我知道为什么会这样?我想使用原生导航