react-native-ble-plx: Bug Report userState React Hooks
Expected Behavior
When using “const [devices, setDevices] = useState([])” or any statefunction inside the scaning from ‘startDeviceScan’ the event stops
Current Behavior
The event stop and no more devices are found
Context
[CoreBluetooth] API MISUSE: <CBCentralManager: 0x281ab8af0> has no restore identifier but the delegate implements the centralManager:willRestoreState: method. Restoring will not be supported 2020-01-19 20:06:06.293648+0100 Zipforce[23222:18432691] [CoreBluetooth] XPC connection invalid [RxBLEKit|DEBG|19:06:06.301]: CentralManager(10765437680) didUpdateState(state: poweredOn)
- Library version: 1.1.1
- Platform: OS.
- Platform logs (XCode):
const bleManager = new BleManager();
const [deviceScan, setDeviceScan] = useState(false)
const [devices, setDevices] = useState([])
const stopDeviceScan = () => {
console.trace('stopDeviceScan')
bleManager.stopDeviceScan()
setDeviceScan(false)
}
const addDevice = (device) => {
console.trace('addDevice')
console.log(device.id, device.name, device.localName)
if (device.isConnectable &&
device.localName &&
devices.findIndex((x) => x.id == device.id) === -1) {
setDevices([...devices, {
id: device.id,
name: device.name,
localName: device.localName,
isConnectable: device.isConnectable,
rssi: device.rssi
}])
}
}
const startDeviceScan = () => {
console.trace('startDeviceScan')
bleManager.startDeviceScan(null, { allowDuplicates: false }, (error, device) => {
if (error) {
console.error(error)
} else {
addDevice(device)
}
})
}
useEffect(() => {
console.trace('Init - Timer')
let timerId = setTimeout(() => {
stopDeviceScan()
}, 15000)
return () => clearTimeout(timerId);
}, [])
useEffect(() => {
console.trace('Init')
setDevices([])
setDeviceScan(true)
const subscription = bleManager.onStateChange((state) => {
switch (state) {
case 'PoweredOn':
console.trace('PoweredOn')
subscription.remove();
startDeviceScan()
break;
default:
break;
}
})
}, [])
useEffect(() =>{
console.log('useEffect',devices)
},[devices])
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Reactions: 4
- Comments: 26 (3 by maintainers)
@Cierpliwy Could you explain why the
BleManagercannot be instantiated inside the component?Also, it would be extremely helpful to have an example
react-native-ble-plximplementation using functional components. Do you know if this exists?I’ve noticed the same thing when using monitorCharacteristicForService(). If I try to update state inside of my listener function, it only runs once and then stops.
Just to make things clear. You shouldn’t create
BleManagerinside the component. Is that true in your case?I dont see that the scanning stops, but I do see that this:
needs to be this :
i believe the problem arrises from the state hook causing a re-render. i fixed it by useRef for the manager and useReducer, rather then useState for storing the devices i get back from the scan.
Yeah, example was prepared to be concise. In general I highly recommend to create clear separation between BLE logic and UI of your application.
@Cierpliwy Wow! Just tried it! Fixed my problem! Damn… that was really stupid of me!
I ve been trying to fix this for at least 2 Days now…
But how come this works inside a Class-Component:
Taken from https://www.polidea.com/blog/ReactNative_and_Bluetooth_to_An_Other_level/
Yes, it is the same and it also works for me. I can’t reproduce the issue then…
Extract the search function and pass in a function to update the state