androidreactjsreact-nativeexpoexpo-camera

TypeError: Cannot read property 'CameraType' of undefined, React Native


I'm currently using expo-camera for camera features, but the app crashes when it tries to start on android device. Here's my js code:

import React, { useState, useEffect, useRef } from 'react';
import { Text, View, TouchableOpacity, Button} from 'react-native';
import { Camera, CameraType } from 'expo-camera';

export default function CameraComp({ navigation }) {

const [type, setType] = useState(CameraType.back);
...
}

When I try to start the app I get the following error: Cannot read property 'CameraType' of undefined. I'm following this tutorial from expo: https://docs.expo.dev/versions/latest/sdk/camera/

My build.gradle:

buildscript {
    ext {
        buildToolsVersion = "33.0.1"
        minSdkVersion = 21
        compileSdkVersion = 33
        targetSdkVersion = 33

        // We use NDK 23 which has both M1 support and is the side-by-side NDK version from AGP.
        ndkVersion = "23.1.7779620"
    }
    repositories {
        google()
        mavenCentral()
    }
    dependencies {
        classpath("com.android.tools.build:gradle")
        classpath("com.facebook.react:react-native-gradle-plugin")
    }
}

Package.json:

...
"dependencies": {
    "expo": "^49.0.13",
    "expo-camera": "~13.4.4",
    "expo-modules-core": "^1.5.11",
    "react": "18.2.0",
    "react-dom": "^18.2.0",
    "react-native": "0.72.5"
}
...

Solution

  • Here is the complete code. This has been tested and working fine.

    import React, { useState, useEffect } from "react";
    import { Text, View, Button, StyleSheet } from "react-native";
    import { Camera, CameraType } from "expo-camera";
    
    export default function CameraComp({ navigation }: any) {
      const [type, setType] = useState(CameraType.back);
      const [permission, requestPermission] = Camera.useCameraPermissions();
    
      useEffect(() => {
        console.log("Permission is granted", permission?.granted);
      }, [permission]);
    
      const toggleCameraType = async () => {
        setType((current) => (current === CameraType.back ? CameraType.front : CameraType.back));
      };
    
      return (
        <View>
          <Text>Camera Comp {type}</Text>
          <Camera style={styles.camera} type={type} />
          <Button title="Grant Permission" onPress={() => requestPermission()} />
          <Button title="Flip Camera" onPress={toggleCameraType} disabled={permission?.granted ? false : true} />
          <Button title="Go to Home" onPress={() => navigation.push("Home")} />
        </View>
      );
    }
    
    const styles = StyleSheet.create({
      camera: {
        width: "100%",
        height: 350,
      },
    });

    On pressing "Grant Permission" button, your mobile device will ask for camera permission. You have to press "Allow" option. Then reload the app again. It should work now.