React Native 功能组件 - 在不同的屏幕之间导航,每个屏幕都在一个单独的 .js 文件中

React Native functional components - Navigate between different screens, each on a separate .js file

在我的基于 功能组件 的 React Native 应用程序中,我想在不同的屏幕之间导航,每个屏幕都驻留在一个单独的 .js 文件中。我希望能够像这样深入地导航多层:

[Screen1.js] <-> [Screen2.js] <-> [Screen3.js] <-> [Screen4.js]

出于某种原因,the examples in the tutorial 将所有屏幕放在同一个 App.js 文件中,每个屏幕都有自己独立的功能,我认为这是不寻常的开发人员行为。

我希望将导航堆栈放在单个 NavigationService.js 文件中,然后由每个 Screen#.js 文件导入。我怎么能实现这个? (我已经看到了几个关于这个的答案,以及一些在线教程,但似乎大多数人都实现了 class 组件而不是 functional.)

下面是我尝试实现此环境的尝试,但是当我尝试导航到新屏幕时,我得到 _NavigationService.default.navigate is not a function. (In '_NavigationService.default.navigate('Email')', '_NavigationService.default.navigate' is undefined)

NavigationService.js:

import * as React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import EmailScreen from './Email';
import HomeScreen from './App';

const Stack = createNativeStackNavigator();
  
function NavigationService( navigation ) {
  return (
    <NavigationContainer>
      <Stack.Navigator initialRouteName="Home">
        <Stack.Screen name="Home" component={HomeScreen} />
        <Stack.Screen name="Camera" component={CameraScreen} />
        <Stack.Screen name="Email" component={EmailScreen} />
      </Stack.Navigator>
    </NavigationContainer>
  );
}

export default {navigation, NavigationService};

App.js(主屏幕):

import * as React from 'react';
import { View, Text, StyleSheet } from 'react-native';
import { Button } from 'react-native-elements';
import NavigationService from './NavigationService';

function HomeScreen() {
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center', backgroundColor: 'white' }}>
    <Button buttonStyle={styles.cameraButton} titleStyle={styles.buttonText}
    onPress={() => NavigationService.navigate('Email')}
    title="Email pics"
    />
    </View>
  );
}

const styles = StyleSheet.create({
  cameraButton: {
    backgroundColor: 'red',
  },
  buttonText: {
    fontSize: 24
  }
});

export default HomeScreen;

Email.js (EmailScreen):

import * as React from 'react';
import { View, Text, StyleSheet } from 'react-native';
import RNSmtpMailer from 'react-native-smtp-mailer';

function EmailScreen() {

    return(
        <View>
            <Text>Test hi hi hi</Text>
        </View>
    )
}
export default EmailScreen;

您不必在个人屏幕中导入 NavigationService。 React Navigation 会处理这个问题并注入一个 navigation 属性 ,你可以使用它来代替。

使用例如

function HomeScreen({ navigation }) {
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center', backgroundColor: 'white' }}>
    <Button buttonStyle={styles.cameraButton} titleStyle={styles.buttonText}
    onPress={() => navigation.navigate('Email')}
    title="Email pics"
    />
    </View>
  );
}

您的 NavigationService 只会在入口点的某处使用以呈现堆栈导航器,我建议重命名它以避免误认为它可以作为服务传递。它只是应用程序层次结构中的一个组件,它建立了导航堆栈,React Navigation 确保堆栈屏幕获得必要的属性,如 navigationroute(例如从中获取导航参数)。

因此,您也不必将 navigation 属性 传递到 NavigationService

Here 是一个很棒的教程,功能组件分布在多个文件中。