首页 文章

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

提问于
浏览
3

我正在使用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 />
}

以下是我的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>
    );
}

请帮我解决这个问题 . 我究竟做错了什么?

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

1 回答

  • 0

    我面临同样的问题 . 切换屏幕时出现严重延迟 . 经过长时间搜索我发现这个非常有用的博客https://novemberfive.co/blog/react-performance-navigation-animations/

    所以问题是

    当按下新屏幕时,React Navigation将首先将其渲染到屏幕外,然后将其设置为动画 . 这意味着当推送具有许多组件的复杂屏幕时,这些组件很容易花费几百毫秒来渲染

    为了解决这个问题,我使用了 InteractionManager . 一旦完成所有动画,它基本上都会给你回调 .

    以下是我为避免延迟所做的工作,应用程序在修复后工作正常 . 希望这可以帮助 .

    // @流

    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;
    

相关问题