I want to graph the data I get from Ble on React-native in real time.
But I am getting this error;
Please help me...
Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null.
Note : If I don't add the isLoading part, I get this error,
Error while updating property 'd' of a view managed by:RNSVGPath InvalidNumber
import React, { Component } from 'react';
import { View, StyleSheet, Dimensions, ActivityIndicator } from 'react-native';
import PropTypes from 'prop-types';
import hr from '../components/CharacteristicCard';
import ScreenContainer from '../components/ScreenContainer';
import Chart from '../components/Chart';
const width = Dimensions.get('window').width;
const height = Math.floor((Dimensions.get('window').height - 150) / 3);
let counter = 0;
const slotsPerWidth = 100;
const initialState = {
flow: [hr],
isLoading: true,
};
class ChartScreen extends Component {
state = {
chartData: { ...initialState },
};
static getDerivedStateFromProps(state) {
counter ;
return {
chartData: {
flow: [hr],
},
};
}
render() {
const { flow } = this.state.chartData;
if (this.state.isLoading) {
return (
<ScreenContainer>
<View style={styles.main}>
<View>
<ActivityIndicator></ActivityIndicator>
</View>
<Chart
key="flow"
data={flow}
maxValue={1900}
minValue={1750}
slotsPerWidth={slotsPerWidth}
width={width}
height={height}
marginBottom={20}
lineColor="rgba(95, 92, 1, 1)"
lineThickness={2}
chartBackground="#17204d"
horizontalGridLinesCount={5}
gridColor="rgba(65, 95, 93, .4)"
gridThickness={1}
unit="ml"
axisTooClose={10}
labelsColor="rgba(255, 255, 255, 0.8)"
labelsFontSize={12}
marginLeft={60}
labelsMarginLeft={15}
/>
</View>
</ScreenContainer>
);
}
};
}
const styles = StyleSheet.create({
main: {
flex: 1,
},
});
export default ChartScreen;
Note (edit): This is my screen,
const DeviceScreen = ({
route,
navigation,
}: StackScreenProps<RootStackParamList, 'Device'>) => {
// get the device object which was given through navigation params
const { device } = route.params;
const [isConnected, setIsConnected] = useState(false);
const [services, setServices] = useState<Service[]>([]);
// handle the device disconnection
const disconnectDevice = useCallback(async () => {
navigation.goBack();
const isDeviceConnected = await device.isConnected();
if (isDeviceConnected) {
await device.cancelConnection();
navigation.navigate('Home');
}
}, [device, navigation]);
useEffect(() => {
const getDeviceInformations = async () => {
// connect to the device
const connectedDevice = await device.connect();
setIsConnected(true);
// discover all device services and characteristics
const allServicesAndCharacteristics = await connectedDevice.discoverAllServicesAndCharacteristics();
// get the services only
const discoveredServices = await allServicesAndCharacteristics.services();
setServices(discoveredServices);
PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
{
title: 'Permission Localisation Bluetooth',
message: 'Requirement for Bluetooth',
buttonNeutral: 'Later',
buttonNegative: 'Cancel',
buttonPositive: 'OK',
}
);
};
getDeviceInformations();
device.onDisconnected(() => {
navigation.navigate('Home');
});
// give a callback to the useEffect to disconnect the device when we will leave the device screen
return () => {
disconnectDevice();
};
}, [device, disconnectDevice, navigation]);
return (
<ScrollView contentContainerStyle={styles.container}>
<TouchableOpacity style={styles.button} onPress={disconnectDevice}>
<Text style={{fontFamily:"SairaExtraCondensedThin",textAlign:"center",fontSize:15,color:"white"}}>Antrenmanı Sonlandır</Text>
</TouchableOpacity>
<View>
<View style={styles.header} >
<Text>{`Name : ${device.name}`}</Text>
<Text>{`Is connected : ${isConnected}`}</Text>
</View>
{services &&
services.map((service) => <ServiceCard service={service} />)}
</View>
<View>
<ChartScreen chartdata />
</View>
</ScrollView>
);
};
CodePudding user response:
You can conditionally return the loading state or loaded state with a simple ternary operator.
return this.state.isLoading
? <ScreenContainer>
...
</ScreenContainer>
: <LoadedStateComponents /> // or this can be null or whatever you'd like
CodePudding user response:
Quick solution looks like, you're going to want to add an else statement to your return statement with JSX.
function render() {
const { flow} = this.state.chartData;
if(this.state.isLoading){
return(
<ScreenContainer>
<View style={styles.main}>
<View>
<ActivityIndicator></ActivityIndicator>
</View>
<Chart
key="flow"
data={flow}
maxValue={1900}
minValue={1750}
slotsPerWidth={slotsPerWidth}
width={width}
height={height}
marginBottom={20}
lineColor="rgba(95, 92, 1, 1)"
lineThickness={2}
chartBackground="#17204d"
horizontalGridLinesCount={5}
gridColor="rgba(65, 95, 93, .4)"
gridThickness={1}
unit="ml"
axisTooClose={10}
labelsColor="rgba(255, 255, 255, 0.8)"
labelsFontSize={12}
marginLeft={60}
labelsMarginLeft={15}
/>
</View>
</ScreenContainer>
);
} else {
// This can also be a <LoadingSpinner /> or likewise component
return null
}
}
The problem is that you CAN'T return nothing, so when it loads and the answer is false, you return nothing and the program halts.