Expo camera breaks on mobile web version with React error


I am trying to use the expo-camera for web. For reference, this is working 100% on Expo Go on my phone. But when I visit my website (hosted on AWS) which has the same build, I get a white screen after accepting camera permissions because of this error

Invalid hook call. Hooks can only be called inside of the body of a
function component. This could happen for one of the following
reasons: 1. You might have mismatching versions of React and the
renderer (such as React DOM) 2. You might be breaking the Rules of
Hooks 3. You might have more than one copy of React in the same app
See https://reactjs.org/link/invalid-hook-call for tips about how to
debug and fix this problem.

I can see in chrome tools (attached to my phone) this error, but it doesn’t look like anything I am doing..

react-native-logs.fx.ts:34 Error: Minified React error #321; visit https://reactjs.org/docs/error-decoder.html?invariant=321 for the full message or use the non-minified dev environment for full errors and additional helpful warnings.
    at V (react.production.min.js:19)
    at Object.t.useRef (react.production.min.js:25)
    at ExponentCamera.web.tsx:30
    at na (react-dom.production.min.js:157)
    at Ia (react-dom.production.min.js:176)
    at Bs (react-dom.production.min.js:271)
    at Sl (react-dom.production.min.js:250)
    at _l (react-dom.production.min.js:250)
    at wl (react-dom.production.min.js:250)
    at dl (react-dom.production.min.js:243)

And this is the code it is referring to, which is of course part of expo

const ExponentCamera = React.forwardRef(
  (
    { type, pictureSize, poster, ...props }: CameraNativeProps & { children?: React.ReactNode },
    ref: React.Ref<ExponentCameraRef>
  ) => {
    const video = React.useRef<HTMLVideoElement | null>(null);

    const native = useWebCameraStream(video, type as CameraType, props, {
      onCameraReady() {
        if (props.onCameraReady) {
          props.onCameraReady();
        }
      },
      onMountError: props.onMountError,
    });

Here is my code

import React from 'react';
import { StyleSheet, Text } from 'react-native';
import { NavigationProp, ParamListBase } from '@react-navigation/native';
import { BarCodeScanningResult, Camera, PermissionResponse, PermissionStatus } from 'expo-camera';

export interface BarCodeScannerScreenProps {
    navigation: NavigationProp<ParamListBase>
}

export const BarCodeScannerScreen = (props: BarCodeScannerScreenProps) => {
    const [cameraPermission, setCameraPermission] = React.useState<string>(PermissionStatus.UNDETERMINED);

    const getPermission = async () => {
        const response: PermissionResponse = await Camera.requestCameraPermissionsAsync();
        setCameraPermission(response.status);
    };

    const onBarCodeScanned = (event: BarCodeScanningResult) => {
        props.navigation.navigate("BookSearch", {searchValue: event.data});
    };

    React.useEffect(() => {
        getPermission();
    }, []);

    if(cameraPermission === PermissionStatus.UNDETERMINED){
        return <Text>Requesting camera permission</Text>;
    }
    else if(cameraPermission === PermissionStatus.GRANTED){
        return (
            <Camera
                onBarCodeScanned={onBarCodeScanned}
                style={StyleSheet.absoluteFill}
            />
        );
    }
    else {
        return <Text>No access to camera</Text>;
    }
}

Maybe I do have some invalid hook or something in my code? But I don’t see why it would work fine on Expo Go.

Source: React – Stack Overflow

November 28, 2021
Category : News
Tags: expo | react native | reactjs

Leave a Reply

Your email address will not be published. Required fields are marked *

Sitemap | Terms | Privacy | Cookies | Advertising

Senior Software Developer

Creator of @LzoMedia I am a backend software developer based in London who likes beautiful code and has an adherence to standards & love's open-source.