javascriptreact-nativeexpo-camera

TypeError: undefined is not an object (evaluating '_this.camera = _ref')


-App dev in React Native- Hello, I have a problem with Expo Camera. Here an error is referred when you want to take a picture.

"TypeError: undefined is not an object (evaluating '_this.camera = _ref')" / Scan.js.

If the app is freshly updated with Expo, everything works. But as soon as you continue programming and another error occurs, this error appears and doesn't go away until you refresh the app again.

I have tried a lot, but I need help here.

Scan.js

import React, { Component, useState, useEffect } from 'react';
import { View, Text, StyleSheet, TouchableOpacity, Image } from 'react-native';
import {launchCamera, launchImageLibrary} from 'react-native-image-picker';
import {Camera, Constants} from 'expo-camera';
import * as MediaLibrary from 'expo-media-library';
import * as Haptics from 'expo-haptics';


import Images from '../assets/icon/index'



const Scan = () => {
  const [hasPermission, setHasPermission] = useState(null);
  const [type, setType] = useState(Camera.Constants.Type.back);
  const [status, requestPermission] = MediaLibrary.usePermissions();
  


  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>;
  }
  
  takePicture = async () => {
    if (this.camera) {
      let photo = await this.camera.takePictureAsync();

      Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Medium);

      console.log(photo.uri);
      MediaLibrary.saveToLibraryAsync(photo.uri);
    }
  };

  
  
  
  

  
  return (
    <View style={styles.container}>
      <Camera style={styles.camera}
        type={type}
        ref={ref => {
          this.camera = ref;
        }}>
        <View style={styles.buttonContainer}>
          <TouchableOpacity
            style={styles.button}
            onPress={() => {
              setType(
                type === Camera.Constants.Type.back
                  ? Camera.Constants.Type.front
                  : Camera.Constants.Type.back
              );
            }}
            >
            <Image source={Images.camera} style={styles.icon}></Image>
          </TouchableOpacity>
          <TouchableOpacity
          style={styles.button}
          onPress={takePicture}
          >
            <Text style={styles.text}>Take</Text>
          </TouchableOpacity>
        </View>
      </Camera>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  camera: {
    flex: 1,
  },
  buttonContainer: {
    flex: 1,
    backgroundColor: 'transparent',
    flexDirection: 'row',
    margin: 20,
    top: 0,
  },
  button: {
    flex: 0.1,
    alignSelf: 'flex-end',
    alignItems: 'center',
  },
  text: {
    fontSize: 18,
    color: 'white',
  },
  icon : {
    tintColor: 'white',
  },
})

export default Scan; ```

Solution

  • Create a new camera reference and attach it to the Camera component.

    import { useRef } from 'react';
    ...
    const cameraRef = useRef<Camera>(null);
    ...
    <Camera ref={cameraRef} ... />
    

    In your takePicture function replace this.camera.takePictureAsync with cameraRef.current?.takePictureAsync