Expo-Camera无法设置扫码间隔,单次扫码触发多次回调问题求助
解决Expo Camera二维码扫描多次触发回调的问题
核心原因
Expo Camera的barcodeSettings.interval仅控制扫描引擎的检测间隔,但在单次检测周期内(比如同一帧画面),扫描引擎可能多次识别到同一个二维码,导致onBarCodeScanned在同一毫秒内连续触发多次,该参数无法解决这类重复触发问题。
解决方案:状态锁+数据去重
通过组件状态控制扫描回调的执行时机,同时记录上一次扫描的二维码数据,避免重复处理同一条码。
修改后的代码示例
import { useState, useCallback } from 'react'; import { View, ToastAndroid } from 'react-native'; import { Camera } from 'expo-camera'; export default function ScannerScreen() { const [type, setType] = useState(Camera.Constants.Type.back); // 标记是否正在处理扫描结果 const [isProcessing, setIsProcessing] = useState(false); // 记录上一次扫描的二维码数据 const [lastScannedData, setLastScannedData] = useState(''); const handleBarCodeScanned = useCallback(async ({ type: typeCode, data }) => { // 正在处理或扫描到重复数据时直接返回 if (isProcessing || data === lastScannedData) return; setIsProcessing(true); setLastScannedData(data); // 执行你的业务逻辑 console.log("NEW code scanned, Type: " + typeCode + " Data: " + data + " Time scan: " + new Date()); ToastAndroid.show("scanned", ToastAndroid.SHORT); // 1秒后解锁,允许下一次扫描(可根据需求调整时长) setTimeout(() => { setIsProcessing(false); // 可选:5秒后清空历史数据,允许重新扫描同一个二维码 // setTimeout(() => setLastScannedData(''), 5000); }, 1000); }, [isProcessing, lastScannedData]); return ( <View style={styles.container}> <Camera barcodeSettings={{ interval: 1000, // 保留该参数控制扫描间隔,配合业务层控制双重保障 }} style={styles.camera} type={type} onBarCodeScanned={handleBarCodeScanned} ratio="16:9" /> </View> ); } const styles = { container: { flex: 1, }, camera: { flex: 1, }, };
备选方案:防抖函数
如果不想手动管理状态锁,可以使用防抖函数来限制回调的执行频率:
代码示例
import { useCallback } from 'react'; import { debounce } from 'lodash'; // ...其他导入 export default function ScannerScreen() { // ...其他状态 const handleBarCodeScanned = useCallback(debounce(async ({ type: typeCode, data }) => { console.log("NEW code scanned, Type: " + typeCode + " Data: " + data + " Time scan: " + new Date()); ToastAndroid.show("scanned", ToastAndroid.SHORT); }, 1000, { leading: true, // 立即执行第一次触发的回调 trailing: false // 忽略防抖时间内的后续触发 }), []); // ...组件返回部分 }
注意事项
- 状态锁方案无需额外依赖,更适合小型项目;防抖函数需要安装lodash(
npm install lodash)。 - 调整解锁/防抖的时长时,需平衡用户体验和扫描灵敏度,避免过长导致用户重复扫码无响应。
内容的提问来源于stack exchange,提问作者user22850906
相关产品推荐
相关产品推荐

