You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Expo Camera无法扫描条码及Camera.Constants调用报错求助

解决Expo Camera二维码扫描问题及替代方案

一、修复当前Expo Camera的错误

1. 确认依赖版本与正确导入

当前expo-camera已不再使用CameraConstants,需通过CameraType枚举或直接使用字符串值设置相机类型。先确保安装最新依赖:

npx expo install expo-camera

然后正确导入组件与类型:

import { Camera, CameraType } from 'expo-camera';

2. 正确设置相机类型

  • 推荐使用枚举值:
<Camera
  type={CameraType.back}
  // 其他必要属性:权限、条码扫描回调等
/>
  • 也可直接使用字符串值:
<Camera
  type="back"
  // 其他必要属性
/>

3. 必加权限处理

相机和条码扫描需要权限,必须先请求权限才能正常运行:

import { useState, useEffect } from 'react';
import { View, Text, Alert } from 'react-native';
import { Camera, CameraType, PermissionStatus } from 'expo-camera';

export default function QrScanner() {
  const [hasPermission, setHasPermission] = useState(null);
  const [scanned, setScanned] = useState(false);

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

  const handleBarCodeScanned = ({ type, data }) => {
    setScanned(true);
    Alert.alert('扫描结果', `类型:${type}\n内容:${data}`);
  };

  if (hasPermission === null) return <View />;
  if (hasPermission === false) return <Text>无相机权限</Text>;

  return (
    <Camera
      style={{ flex: 1 }}
      type={CameraType.back}
      onBarCodeScanned={scanned ? undefined : handleBarCodeScanned}
    />
  );
}

4. 排查Element type is invalid错误

该错误通常因组件导入错误导致,比如你可能写成了:

import * as Camera from 'expo-camera';
// 此时需用<Camera.Camera />而非<Camera />

要么改为import { Camera } from 'expo-camera',要么使用<Camera.Camera />调用组件。

二、替代二维码扫描方案

如果Expo Camera仍有问题,可尝试以下方案:

1. 使用expo-barcode-scanner

Expo官方轻量化条码扫描库,配置更简单:

npx expo install expo-barcode-scanner

示例代码:

import { useState, useEffect } from 'react';
import { Text, View, StyleSheet, Button } from 'react-native';
import { BarCodeScanner } from 'expo-barcode-scanner';

export default function BarcodeScannerExample() {
  const [hasPermission, setHasPermission] = useState(null);
  const [scanned, setScanned] = useState(false);

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

  const handleBarCodeScanned = ({ type, data }) => {
    setScanned(true);
    Alert.alert('扫描成功', `类型:${type}\n内容:${data}`);
  };

  if (hasPermission === null) return <Text>请求相机权限中...</Text>;
  if (hasPermission === false) return <Text>无相机权限</Text>;

  return (
    <View style={styles.container}>
      <BarCodeScanner
        onBarCodeScanned={scanned ? undefined : handleBarCodeScanned}
        style={StyleSheet.absoluteFillObject}
      />
      {scanned && <Button title="重新扫描" onPress={() => setScanned(false)} />}
    </View>
  );
}

const styles = StyleSheet.create({
  container: { flex: 1, justifyContent: 'center' },
});

2. 使用react-native-vision-camera(裸项目/EAS构建)

适合裸React Native项目或使用EAS构建的Expo项目,性能更优:

# 安装核心库
npm install react-native-vision-camera
# 安装条码扫描插件
npm install vision-camera-code-scanner

配置步骤:

  • 在babel.config.js中添加插件:
module.exports = {
  plugins: [
    ['react-native-reanimated/plugin'],
    ['vision-camera-code-scanner', { scanner: 'zxing' }],
  ],
};
  • 配置相机权限(添加到app.json/AndroidManifest.xml/Info.plist)

示例代码:

import { useState } from 'react';
import { StyleSheet, View, Button } from 'react-native';
import { Camera, useCameraDevices } from 'react-native-vision-camera';
import { useCodeScanner } from 'vision-camera-code-scanner';

export default function QrScanner() {
  const [scanned, setScanned] = useState(false);
  const devices = useCameraDevices();
  const device = devices.back;

  const codeScanner = useCodeScanner({
    codeTypes: ['qr'],
    onCodeScanned: (codes) => {
      if (!scanned) {
        setScanned(true);
        Alert.alert('扫描结果', codes[0].value);
      }
    },
  });

  if (!device) return <View />;

  return (
    <View style={styles.container}>
      <Camera
        style={styles.camera}
        device={device}
        isActive={true}
        codeScanner={codeScanner}
      />
      {scanned && <Button title="重新扫描" onPress={() => setScanned(false)} />}
    </View>
  );
}

const styles = StyleSheet.create({
  container: { flex: 1 },
  camera: { flex: 1 },
});

内容的提问来源于stack exchange,提问作者Dhananjay Ahlawat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 00:22:07