简体   繁体   中英

Expo Ref usage and Navigation Container Conflicting

I am using Expo Camera to take some user pictures for a profile form. What is happening is when I try to set camera's ref to a state it crashes and throw the following error.

Couldn't find a navigation context. Have you wrapped your app with 'NavigationContainer'? See https://reactnavigation.org/docs/getting-started for setup instructions.

Everything is inside a Navigation Container and I really can't figure out what is happening.

Every time I comment ref={(ref) => console.tron.log(ref)} from Expo Camera component everything works fine, but when I uncomment the ref line I get the error.

I am stuck here since last week and nothing on internet about this problem...

Thanks in advance =)

错误说我可能没有在导航容器内使用

App.js

import React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { AuthProvider } from './src/context/authContext';

import Routes from './src/routes';
import Theme from './src/theme';
import './src/config/reactotron.config';

export default function App() {
    return (
        <Theme>
            <AuthProvider>
                <NavigationContainer>
                    <Routes />
                </NavigationContainer>
            </AuthProvider>
        </Theme>
    );
}

routes.js

import React from 'react';
import { createStackNavigator } from '@react-navigation/stack';

import arrowLeft from '../../assets/img/arrow-left-header.png';

import SignUp from '../pages/auth/SignUp';
import Profile from '../pages/auth/Profile';
import Login from '../pages/auth/Login';
import Habits from '../pages/auth/Habits';
import AddChildren from '../pages/auth/AddChildren';
import ChildProfile from '../pages/auth/ChildProfile';
import RegisterFinish from '../pages/auth/RegisterFinish';
import { CameraView } from '../components';

const AuthStack = createStackNavigator();
const theme = {
    color: {
        brandPrimary: '#16B4A1',
        white: '#fff',
    },
};

const AuthRoutes = () => {
    return (
        <AuthStack.Navigator
            screenOptions={{
                headerTintColor: theme.color.white,
                headerStyle: {
                    backgroundColor: theme.color.brandPrimary,
                },
                cardStyle: {
                    backgroundColor: theme.color.white,
                },
                headerBackTitle: 'Voltar',
            }}
        >
            <AuthStack.Screen
                name='Profile'
                component={Profile}
                options={{
                    headerLeft: null,
                }}
            />
            <AuthStack.Screen
                name='Login'
                component={Login}
                options={{ headerShown: false }}
            />

            <AuthStack.Screen
                name='SignUp'
                component={SignUp}
                options={{ headerShown: false }}
            />
            
            <AuthStack.Screen
                name='RegisterFinish'
                component={RegisterFinish}
                options={{
                    headerLeft: null,
                    headerShown: false,
                }}
            />
            <AuthStack.Screen
                name='TakeAPicture'
                component={CameraView}
                options={{
                    headerLeft: null,
                    headerShown: false,
                }}
            />
            <AuthStack.Screen name='Habits' component={Habits} />
            <AuthStack.Screen name='AddChildren' component={AddChildren} />
            <AuthStack.Screen name='ChildProfile' component={ChildProfile} />
        </AuthStack.Navigator>
    );
};

export default AuthRoutes;

CameraView.js

import React, { useState, useEffect, useRef } from 'react';
import { View, Text, TouchableOpacity } from 'react-native';
import PropTypes from 'prop-types';
import { Camera } from 'expo-camera';
import { FontAwesome5 } from '@expo/vector-icons';

import { CameraButton, CameraButtonRing } from './styles';

const CameraView = ({ route, navigation }) => {
    const cameraRef = useRef()
    // CAMERA SETTINGS
    const [hasPermission, setHasPermission] = useState(null);
    const [type, setType] = useState(Camera.Constants.Type.front);

    useEffect(() => {
        console.tron.log('rolou')
        async function handleCameraPermission() {
            const { status } = await Camera.requestPermissionsAsync();
            setHasPermission(status === 'granted');
        }
        handleCameraPermission();
    }, []);

    const handleTakePictureButton = async () => {
        if (!cameraRef) {
            console.tron.log('Não tem cam ref')
            return
        };
        let photo = await cameraRef.takePictureAsync();
        console.tron.log(photo)
        handlePicture(photo)
    }

    return (
        <View style={{ flex: 1 }}>
            <Camera
                style={{ flex: 1 }}
                type={type}
                ref={(ref) => console.tron.log(ref)}
            >
                <View
                    style={{
                        flex: 1,
                        backgroundColor: 'transparent',
                        flexDirection: 'row',
                        border: '1px solid red '
                    }}
                >
                    <TouchableOpacity
                        style={{
                            // flex: ,
                            // alignSelf: 'flex-end',
                            // alignItems: 'center',
                            position: 'absolute',
                            bottom: 40,
                            right: 32,
                        }}
                        onPress={() => {
                            setType(
                                type === Camera.Constants.Type.back
                                    ? Camera.Constants.Type.front
                                    : Camera.Constants.Type.back
                            );
                        }}
                    >
                        <FontAwesome5 name='sync-alt' size={32} color='#fff' />
                    </TouchableOpacity>

                    <TouchableOpacity
                        style={{
                            // flex: 0.1,
                            alignSelf: 'flex-end',
                            height: 56,
                            width: 56,
                            backgroundColor: 'transparent',
                            marginLeft: 'auto',
                            marginRight: 'auto',
                            marginBottom: 24,
                            border: '1px solid red'
                        }}
                        onPress={handleTakePictureButton}
                    >
                        <View style={{position: 'relative'}}>
                            <CameraButton />
                            <CameraButtonRing />
                        </View>
                    </TouchableOpacity>
                </View>
            </Camera>
        </View>
    );
};


export default CameraView;

For anyone stumbling on this, I really don't know the reason behind, but what was crashing my app with the exact same error, was trying to log to Reactotron. It was the only thing in common with the code on the question, and after removing that, the application stopped crashing and worked just fine.

Now... if anyone discovers the reason, I would really like to know as well.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM