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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 20:45:23