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

使用Expo React Native集成react-native-vision-camera遇相机启动错误求助

解决React Native Expo中react-native-vision-camera的getAvailableCameraDevices为null的问题

错误原因分析

TypeError: Cannot read property 'getAvailableCameraDevices' of null 本质是相机模块在未获取到权限的情况下尝试访问设备列表,或是权限请求逻辑未正确执行导致相机模块未完成初始化。

具体修复步骤

1. 修复权限请求的执行逻辑

你的useEffect里仅引用了requestCameraPermission变量,没有实际调用该函数,导致权限根本没发起请求。同时要确保useEffect的依赖数组包含这个回调函数:

React.useEffect(()=>{
  requestCameraPermission(); // 加上()执行函数
},[requestCameraPermission]) // 添加依赖确保回调更新时重新执行

2. 新增权限状态跟踪,避免提前初始化相机

添加状态变量记录权限状态,只有当权限通过后再渲染相机相关逻辑,避免useCameraDevices在权限未就绪时执行:

const [hasCameraPermission, setHasCameraPermission] = React.useState(false);

// 修改权限请求回调,更新权限状态
const requestCameraPermission = React.useCallback(async ()=>{
    const permission = await Camera.requestCameraPermission();
    if(permission === 'granted'){
      setHasCameraPermission(true);
    } else if(permission === 'denied'){
      await Linking.openSettings()
    }
},[])

3. 调整相机初始化逻辑,依赖权限状态

仅当hasCameraPermission为true时,才调用useCameraDevices,同时使用可选链避免null报错:

const devices = hasCameraPermission ? useCameraDevices('wide-angle-camera') : null;
const device = devices?.back;

4. 配置Expo权限声明

在项目根目录的app.json中添加相机权限描述,iOS必须配置NSCameraUsageDescription,Android需要添加CAMERA权限:

{
  "expo": {
    "ios": {
      "infoPlist": {
        "NSCameraUsageDescription": "需要访问相机进行产品扫描"
      }
    },
    "android": {
      "permissions": ["CAMERA"]
    }
  }
}

修改后的完整代码

import React from 'react';
import { View, Linking } from 'react-native';
import { Camera, useCameraDevices } from 'react-native-vision-camera';

const ScanProduct =({navigation})=>{
    const [hasCameraPermission, setHasCameraPermission] = React.useState(false);

    // 仅当权限通过后才获取相机设备
    const devices = hasCameraPermission ? useCameraDevices('wide-angle-camera') : null;
    const device = devices?.back;

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

    const requestCameraPermission = React.useCallback(async ()=>{
        const permission = await Camera.requestCameraPermission();
        if(permission === 'granted'){
          setHasCameraPermission(true);
        } else if(permission === 'denied'){
          await Linking.openSettings()
        }
    },[])

    function renderCamera(){
        if(device == null){
          return(
            <View style={{flex:1}}/>
          )
        } else{
          return(
            <View style={{flex:1}}>
              <Camera
                style={{flex:1}}
                device={device}
                isActive={true}
                enableZoomGesture
              />
            </View>
          )
        }
    }

    return(
        <View style={{flex:1}}>
            {hasCameraPermission && renderCamera()}
        </View>
    )
}

export default ScanProduct;

额外注意事项

  • 确保react-native-vision-camera版本与当前Expo SDK兼容,部分高版本的vision-camera可能需要使用Expo Dev Client而非Expo Go(Expo Go不支持自定义原生模块配置),如果上述修复后仍有问题,可以尝试切换到Expo Dev Client测试。
  • iOS上第一次拒绝权限后,再次请求会直接跳转设置页面,你的代码已处理该逻辑,无需额外修改。

内容的提问来源于stack exchange,提问作者Bashamlan Salem

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 00:32:52