You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Hello. Is it possible to accomplish this?
I would like to re-render only the component which has rssi value in it, but the component with device name should stay the same.
import{View,Text}from'react-native';importReact,{useEffect}from'react';importuseBLEfrom'@/hooks/useBLE';import{Button}from'react-native-paper';import{FlashList}from'@shopify/flash-list';import{Device}from'react-native-ble-plx';constHomeScreen=()=>{const{allDevices, scanForPeripherals, requestPermissions}=useBLE();useEffect(()=>{constscanForDevices=()=>{requestPermissions(isGranted=>{if(isGranted){scanForPeripherals();}});};scanForDevices();},[]);constkeyExtractor=(item: Device)=>item.id;return(<View><Textstyle={{fontSize: 28,marginBottom: 18}}>HomeScreen</Text><Viewstyle={{height: 500}}><Textstyle={{fontSize: 24}}>AllDevices</Text><FlashListdata={allDevices}keyExtractor={keyExtractor}renderItem={({item})=>(<Viewkey={item.id}style={{flexDirection: 'row',justifyContent: 'space-evenly',alignItems: 'center',marginTop: 10,}}>{/* DON'T RE-RENDER IF A RSSI VALUE HAS CHANGED */}<BluetoothDeviceNamedeviceName={item.name}/><View><Text>-</Text></View>{/* RE-RENDER IF RSSI VALUES HAS CHANGED */}<BluetoothDeviceRssirssi={item.rssi}/></View>)}estimatedItemSize={80}/></View></View>);};exportdefaultHomeScreen;constBluetoothDeviceName=({deviceName}: {deviceName: string|null})=>{return(<View><Buttonmode="contained">{deviceName}</Button></View>);};constBluetoothDeviceRssi=({rssi}: {rssi: number|null})=>{return(<View><Buttonmode="outlined">rssi: {rssi}</Button></View>);};
What I should do in my scanning bluetooth devices function: scanForPeripherals and FlashList to re-render only the BluetoothDeviceRssi component, but BluetoothDeviceName should stay the same?
useBle.tsx
import{Dispatch,useState}from'react';import{PermissionsAndroid,Platform}from'react-native';import{BleManager,Device}from'react-native-ble-plx';import{PERMISSIONS,requestMultiple}from'react-native-permissions';importDeviceInfofrom'react-native-device-info';constbleManager=newBleManager();typeVoidCallback=(result: boolean)=>void;interfaceBluetoothLowEnergyApi{requestPermissions(cb: VoidCallback): Promise<void>;scanForPeripherals(): void;allDevices: Device[];setAllDevices: Dispatch<React.SetStateAction<Device[]>>;}functionuseBLE(): BluetoothLowEnergyApi{const[allDevices,setAllDevices]=useState<Device[]>([]);// console.log('🚀 ~ useBLE ~ freshAllDevices:', freshAllDevices);constrequestPermissions=async(cb: VoidCallback)=>{if(Platform.OS==='android'){constapiLevel=awaitDeviceInfo.getApiLevel();if(apiLevel<31){constgranted=awaitPermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,{title: 'Location Permission',message: 'Bluetooth Low Energy requires Location',buttonNeutral: 'Ask Later',buttonNegative: 'Cancel',buttonPositive: 'OK',},);cb(granted===PermissionsAndroid.RESULTS.GRANTED);}else{constresult=awaitrequestMultiple([PERMISSIONS.ANDROID.BLUETOOTH_SCAN,PERMISSIONS.ANDROID.BLUETOOTH_CONNECT,PERMISSIONS.ANDROID.ACCESS_FINE_LOCATION,]);constisGranted=result['android.permission.BLUETOOTH_CONNECT']===PermissionsAndroid.RESULTS.GRANTED&&result['android.permission.BLUETOOTH_SCAN']===PermissionsAndroid.RESULTS.GRANTED&&result['android.permission.ACCESS_FINE_LOCATION']===PermissionsAndroid.RESULTS.GRANTED;cb(isGranted);}}else{cb(true);}};constisDuplicateDevice=(devices: Device[],nextDevice: Device)=>devices.findIndex(device=>nextDevice.id===device.id)>-1;constisRssiChanged=(devices: Device[],nextDevice: Device)=>devices.findIndex(device=>nextDevice.rssi!==device.rssi)>-1;constscanForPeripherals=()=>{returnbleManager.startDeviceScan(null,null,(error,device)=>{// console.log('🚀 ~ bleManager.startDeviceScan ~ ^^^ device ^^^:', device);if(error){console.log('startDeviceScan error',JSON.stringify(error));}if(device&&device.name!==null&&device.localName!==null){setAllDevices((prevState: Device[])=>{if(!isDuplicateDevice(prevState,device)){//! HEREif(isRssiChanged(prevState,device)){//? remove the old device with the old rssi valueconstfilteredPrevState=prevState.filter(oldDevice=>oldDevice.id!==device.id);console.log('🚀 ~ setAllDevices ~ filteredPrevState:',filteredPrevState);//? put the new device with the new rssi value and re-render the FlashList item where rssi value has changedreturn[...filteredPrevState,device];}return[...prevState,device];}returnprevState;});}});};return{
scanForPeripherals,
requestPermissions,
allDevices,
setAllDevices,};}exportdefaultuseBLE;
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
Hello. Is it possible to accomplish this?
I would like to re-render only the component which has rssi value in it, but the component with device name should stay the same.
What I should do in my scanning bluetooth devices function:
scanForPeripherals
and FlashList to re-render only theBluetoothDeviceRssi
component, butBluetoothDeviceName
should stay the same?useBle.tsx
Beta Was this translation helpful? Give feedback.
All reactions