React Native使用react-native-ble-plx扫描蓝牙设备报TypeError错误求助
问题:React Native蓝牙扫描代码报错TypeError: Cannot read property 'prototype' of undefined
错误信息
This error is located at: in App in RCTView (created by View) in View (created by AppContainer) in RCTView (created by View) in View (created by AppContainer) in AppContainer in BluetoothProje(RootComponent), js engine: hermes ERROR TypeError: Cannot read property 'prototype' of undefined
代码示例
import React, { useState, useEffect } from 'react'; import { SafeAreaView, View, Text, Button, StyleSheet, FlatList, } from 'react-native'; import BleManager from 'react-native-ble-plx'; const App = () => { const [devices, setDevices] = useState([]); const [scanning, setScanning] = useState(false); const bleManager = new BleManager(); useEffect(() => { // Start the BLE manager when the component is mounted bleManager.start(); // Subscribe to device discovery events bleManager.onDeviceDiscovered(device => { setDevices(prevDevices => [...prevDevices, device]); }); return () => { // Stop the BLE manager and unsubscribe from events when the component unmounts bleManager.stop(); bleManager.removeAllListeners(); }; }, []); const startScan = () => { setScanning(true); setDevices([]); bleManager.startDeviceScan(null, null, (error, device) => { if (error) { // Handle error console.log(error); } if (device) { // Device was discovered console.log(device); } }); }; const stopScan = () => { setScanning(false); bleManager.stopDeviceScan(); }; return ( <SafeAreaView style={styles.container}> {scanning ? ( <Button title="Stop Scan" onPress={stopScan} /> ) : ( <Button title="Start Scan" onPress={startScan} /> )} <FlatList data={devices} keyExtractor={item => item.id} renderItem={({ item }) => ( <View style={styles.deviceContainer}> <Text style={styles.deviceName}>{item.name}</Text> <Text style={styles.deviceId}>{item.id}</Text> </View> )} /> </SafeAreaView> ); }; const styles = StyleSheet.create({ container: { flex: 1, justifyContent: 'center', alignItems: 'center', }, deviceContainer: { padding: 16, borderBottomWidth: 1, borderBottomColor: '#ccc', }, deviceName: { fontSize: 18, fontWeight: 'bold', }, deviceId: { fontSize: 14, color: '#666', }, }); export default App;
解决步骤
检查包版本兼容性:这个错误多因
react-native-ble-plx版本与React Native版本不匹配导致。如果RN版本在0.70+,重新安装最新稳定版:npm uninstall react-native-ble-plx npm install react-native-ble-plx确保原生模块链接完整:RN 0.60+自动链接,但偶尔会出现异常,执行以下命令修复:
# iOS npx pod-install # Android cd android && ./gradlew clean修正BleManager实例化方式:不要在组件函数内部直接创建实例,改为组件外部初始化或用
useRef保存,避免重渲染时重复创建:// 方案1:移到组件外部初始化 import BleManager from 'react-native-ble-plx'; const bleManager = new BleManager(); const App = () => { // 剩余代码不变 }; // 方案2:使用useRef保存实例 const bleManager = useRef(new BleManager()).current;补全Android权限配置:在
AndroidManifest.xml中添加蓝牙相关权限:<uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <!-- Android 12+ 需额外权限 --> <uses-permission android:name="android.permission.BLUETOOTH_SCAN" /> <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />修复扫描逻辑冲突:原代码同时使用
onDeviceDiscovered监听和startDeviceScan回调,易导致冲突。保留一种方式即可,比如去掉onDeviceDiscovered监听,直接在扫描回调中更新设备列表(还能避免重复添加设备):useEffect(() => { bleManager.start(); return () => { bleManager.stop(); bleManager.removeAllListeners(); }; }, []); const startScan = () => { setScanning(true); setDevices([]); bleManager.startDeviceScan(null, null, (error, device) => { if (error) { console.log(error); setScanning(false); return; } if (device) { setDevices(prev => { if (!prev.find(d => d.id === device.id)) { return [...prev, device]; } return prev; }); } }); };
内容的提问来源于stack exchange,提问作者profundusman
相关产品推荐
相关产品推荐

