尝试导航到将在 phone 上打开相机的文件时,undefined 不是对象(正在评估 'navigation.navigate')

undefined is not an object (evaluating 'navigation.navigate') when trying to navigate to a file that will open camera on the phone

我正在尝试导航到我的页面“CameraPage.js”,但我收到此错误“undefined is not an object (evaluating 'navigation.navigate')”。任何人都可以看到问题吗?这是我在这里的第一个问题,所以请告诉我是否可以更具体。

这是我的 App.js:

import { StyleSheet, Text, View, TouchableOpacity, Pressable } from 'react-native';
import React, {useEffect, useState} from "react";
import { FontAwesome } from '@expo/vector-icons';
import { useNavigation } from '@react-navigation/native';


export default function App({ navigation }) {

    return (
        <View style={styles.container}>
            <View style={styles.buttonContainer}>
                <TouchableOpacity onPress ={() => navigation.navigate('CameraFunction')}>
            <FontAwesome name="camera" size={100} color="#FFB6C1" />
                </TouchableOpacity>
                <Pressable>
            <FontAwesome name="photo" size={100} color="#FFB6C1" />
                </Pressable>
            </View>
        </View>
    );
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
        backgroundColor: '#FFDBE9'
    },
    buttonContainer: {
        backgroundColor: 'transparent',
        justifyContent: 'space-between',
    },
});
这是我的 CameraPage.js 文件:

import {StyleSheet, Text, View, TouchableOpacity} from 'react-native';
import {Camera, CameraType} from 'expo-camera';
import {useEffect, useState} from "react";


export default function CameraPage() {
    const [hasPermission, setHasPermission] = useState(null);
    const [type, setType] = useState(CameraType.back);

    useEffect(() => {
        (async () => {
            const {status} = await Camera.requestCameraPermissionsAsync();
            setHasPermission(status === 'granted');
        })();
    }, []);

    if (hasPermission === null) {
        return <View/>;
    }
    if (hasPermission === false) {
        return <Text>No access to camera</Text>;
    }
    return (
        <View style={styles.container}>
            <Camera style={styles.camera} type={type}>
                <View style={styles.buttonContainer}>
                    <TouchableOpacity
                        style={styles.button}
                        onPress={() => {
                            setType(type === CameraType.back ? CameraType.front : CameraType.back);
                        }}>
                        <Text style={styles.text}> Flip </Text>
                    </TouchableOpacity>
                </View>
            </Camera>
        </View>
    );
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
    },
    camera: {
        flex: 1,
    },
    buttonContainer: {
        flex: 1,
        backgroundColor: 'transparent',
        flexDirection: 'row',
        margin: 20,
    },
    button: {
        flex: 0.1,
        alignSelf: 'flex-end',
        alignItems: 'center',
    },
    text: {
        fontSize: 18,
        color: 'white',
    },
});
这是我的导航文件:

import React from 'react';
import {createStackNavigator} from '@react-navigation/stack';
import {NavigationContainer} from '@react-navigation/native';
import CameraPage from "../Camera/CameraPage";

const Routes = createStackNavigator();

export default function Navigator() {
    return (
        <NavigationContainer>
            <Routes.Navigator>
                <Routes.Screen
                    name="CameraFunction"
                    component={CameraPage}
                    />
            </Routes.Navigator>
        </NavigationContainer>
    );
}

您的导航容器必须包裹在您的应用程序的根周围,否则导航对象将不会传递给您定义为屏幕的组件。

以下解决了您的问题。

export default const App = () => {
    return (
        <NavigationContainer>
            <Routes.Navigator>
                <Routes.Screen name="Home" component={HomeScreen} />
                <Routes.Screen
                    name="CameraFunction"
                    component={CameraPage}
                    />
            </Routes.Navigator>
        </NavigationContainer>
    );
}

您的 HomeScreen 包含来自 App 的旧代码,但现在您可以访问导航对象,因为我们已将 HomeScreen 定义为导航器内的屏幕。它将由导航框架传递到该屏幕。还要注意 HomeScreen 是您的应用程序的初始屏幕。

export default function HomeScreen({ navigation }) {

    return (
        <View style={styles.container}>
            <View style={styles.buttonContainer}>
                <TouchableOpacity onPress ={() => navigation.navigate('CameraFunction')}>
            <FontAwesome name="camera" size={100} color="#FFB6C1" />
                </TouchableOpacity>
                <Pressable>
            <FontAwesome name="photo" size={100} color="#FFB6C1" />
                </Pressable>
            </View>
        </View>
    );
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
        backgroundColor: '#FFDBE9'
    },
    buttonContainer: {
        backgroundColor: 'transparent',
        justifyContent: 'space-between',
    },
});

请注意,导航到 CameraPage 后需要导航回主屏幕。您也可以使用 CameraPage 中的导航对象并触发 navigation.goBack 来实现此效果。

您只需在 App.js 文件中使用 @react-navigation/native-stack 代替 @react-navigation/stack 然后它将完美运行,

import * as React from 'react';
import {NavigationContainer} from '@react-navigation/native';
import {createNativeStackNavigator} from '@react-navigation/native-stack';
import Home from './TopTabBar/Home';
import 'react-native-gesture-handler';

const Stack = createNativeStackNavigator();

function App() {
  return (
    <NavigationContainer>
      <Stack.Navigator>
        <Stack.Screen name="Home" component={Home} />
      </Stack.Navigator>
    </NavigationContainer>
  );
}

export default App;