React Native安装视觉相机等库后报错及二维码扫描器实现求助
解决Frame Processor错误 + 实现二维码扫描功能
一、修复「Frame Processor threw an error: Value is undefined, expected an Object」错误
这个问题大多是依赖配置不完整或Frame Processor函数写法不符合要求导致的,按以下步骤排查:
1. 确认Reanimated Babel配置正确
在项目根目录的babel.config.js中,必须将Reanimated插件放在所有插件的最后:
module.exports = { presets: ['module:metro-react-native-babel-preset'], plugins: [ // 其他插件(如react-native-screens等)放在前面 'react-native-reanimated/plugin', ], };
配置完成后清除缓存重启服务:
npx react-native start --reset-cache
2. 启用Vision Camera的Frame Processor支持
- iOS:在
ios/Podfile最顶部添加以下代码,然后重新安装Pods:
执行命令:$RNVCameraEnableFrameProcessor = truecd ios && pod install && cd .. - Android:在
android/app/build.gradle的defaultConfig块中添加配置:defaultConfig { // 原有配置... resValue "bool", "RNVCameraEnableFrameProcessor", "true" }
3. 规范Frame Processor函数写法
所有用于帧处理的函数必须添加'worklet'标记,确保函数在UI线程外执行:
const scanProcessor = (frame) => { 'worklet'; // 帧处理逻辑 };
二、实现二维码扫描(替代弃用的QRScanner)
推荐使用react-native-vision-camera + @visioncamera/barcode-scanner组合,这是目前React Native生态中最稳定的条码扫描方案。
1. 安装依赖
npm install react-native-vision-camera @visioncamera/barcode-scanner react-native-reanimated # 或使用yarn yarn add react-native-vision-camera @visioncamera/barcode-scanner react-native-reanimated
2. 配置相机权限
- iOS:在
ios/[项目名]/Info.plist中添加相机权限描述:<key>NSCameraUsageDescription</key> <string>需要访问相机进行二维码扫描</string> - Android:在
android/app/src/main/AndroidManifest.xml中添加权限:<uses-permission android:name="android.permission.CAMERA" />
3. 核心代码实现
import React, { useState, useEffect } from 'react'; import { View, Text, StyleSheet, Platform, PermissionsAndroid } from 'react-native'; import { Camera, useCameraDevices, useFrameProcessor } from 'react-native-vision-camera'; import { BarcodeScanner, BarcodeFormat } from '@visioncamera/barcode-scanner'; import { runOnJS } from 'react-native-reanimated'; const QrScannerScreen = () => { const [hasCameraPermission, setHasCameraPermission] = useState(false); const [scannedResult, setScannedResult] = useState(null); const devices = useCameraDevices(); const backCamera = devices.back; // 请求相机权限 useEffect(() => { const requestPermission = async () => { const iosPerm = await Camera.requestCameraPermission(); let androidPerm = true; if (Platform.OS === 'android') { androidPerm = await PermissionsAndroid.request( PermissionsAndroid.PERMISSIONS.CAMERA ) === PermissionsAndroid.RESULTS.GRANTED; } setHasCameraPermission(iosPerm === 'authorized' && androidPerm); }; requestPermission(); }, []); // 帧处理器:实时扫描二维码 const frameProcessor = useFrameProcessor((frame) => { 'worklet'; // 只扫描QR_CODE格式 const barcodes = BarcodeScanner.scan(frame, [BarcodeFormat.QR_CODE]); if (barcodes.length > 0) { // 将扫描结果同步到JS线程 runOnJS(setScannedResult)(barcodes[0].displayValue); // 可选:扫描到结果后暂停相机 // runOnJS(() => cameraRef.current?.pausePreview())(); } }, []); if (!backCamera) return <Text>加载相机设备中...</Text>; if (!hasCameraPermission) return <Text>请授予相机权限</Text>; return ( <View style={styles.container}> {/* 相机预览 */} <Camera style={StyleSheet.absoluteFill} device={backCamera} isActive={true} frameProcessor={frameProcessor} frameProcessorFps={8} // 平衡扫描灵敏度与性能,可调整 /> {/* 自定义扫描框遮罩(替代react-native-hole,避免依赖冲突) */} <View style={styles.maskLayer}> <View style={styles.scanFrame} /> </View> {/* 扫描结果展示 */} {scannedResult && ( <View style={styles.resultBox}> <Text style={styles.resultText}>扫描结果:{scannedResult}</Text> </View> )} </View> ); }; const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#000', }, maskLayer: { flex: 1, backgroundColor: 'rgba(0,0,0,0.7)', justifyContent: 'center', alignItems: 'center', }, scanFrame: { width: 260, height: 260, borderWidth: 2, borderColor: '#fff', borderRadius: 12, }, resultBox: { position: 'absolute', bottom: 60, left: 24, right: 24, backgroundColor: 'rgba(255,255,255,0.95)', padding: 16, borderRadius: 8, }, resultText: { fontSize: 16, color: '#333', textAlign: 'center', }, }); export default QrScannerScreen;
4. 常见问题排查
- 若仍出现Frame Processor错误:
- 确认所有依赖版本兼容(建议使用
react-native-vision-camera和@visioncamera/barcode-scanner的最新稳定版) - 彻底清理缓存:删除
node_modules、ios/Pods、android/build目录,重新安装依赖 - 暂时移除
react-native-hole,先确保扫描功能正常,再尝试集成遮罩(可用上述代码中的自定义遮罩替代)
- 确认所有依赖版本兼容(建议使用
- 扫描灵敏度低:可提高
frameProcessorFps值(最大不超过15),或确保二维码处于扫描框中央
内容的提问来源于stack exchange,提问作者React_Coder
相关产品推荐
相关产品推荐

