I have two-component classes. First is TrackRoute1.js from which I'm passing bus location parameters and also user current location parameters to class Dispaly.js through the server. But after displaying I keep getting a memory leak that indicates that it cant perform react state update on an unmounted component. I tried everything. But it won't help.!
TrackRoute1.js
import React, { Component } from "react";
import {
ActivityIndicator,
FlatList,
Text,
View,
TouchableHighlight,
StyleSheet,
} from "react-native";
import AnimatedRegion from "react-native-maps";
import Display1 from "./Display1";
import { LogBox } from "react-native";
import CustomHeader from "../CustomHeader";
LogBox.ignoreLogs(["Setting a timer"]);
import * as Location from 'expo-location';
export default class App extends Component {
constructor(props) {
super(props);
this.state = {
data: [],
isLoading: true,
userLat: 0,
userLng: 0,
routeCoordinates: [],
distanceTravelled: 0,
prevLatLng: {},
coordinate: new AnimatedRegion({
userLat: 0,
userLng: 0,
latitudeDelta: 0,
longitudeDelta: 0
})
};
}
componentDidMount() {
this.interval = setInterval(() => this.getCoords(), 1000);
this._getLocationAsync();
}
async getCoords() {
fetch("https://api.thingspeak.com/channels/1323137/feeds.json?results=1")
.then((response) => response.json())
.then((json) => {
console.log(json.feeds, "API res");
this.setState({ data: json.feeds });
})
.catch((error) => console.error(error))
.finally(() => {
this.setState({ isLoading: false });
});
}
_getLocationAsync = async () => {
console.log("123")
let { status } = await Location.requestForegroundPermissionsAsync();
console.log(status)
if (status !== 'granted') {
console.log('Permission to access location was denied');
return;
}
// Old method //
let location = await Location.getCurrentPositionAsync({});
console.log(location, "my location");
this.setState({
userLat: Number(location.coords.latitude),
userLng: Number(location.coords.longitude)
})
console.log(this.state.userLng,"userLng111")
// New Method //
// this.location = await Location.watchPositionAsync(
// {
// enableHighAccuracy: true,
// distanceInterval: 1,
// timeInterval: 1000
// },
// newLocation => {
// let { coords } = newLocation;
// // console.log(coords);
// this.setState({
// userLat: Number(coords.latitude),
// userLng: Number(coords.longitude)
// })
// },
// error => console.log(error)
// );
// return this.location;
};
calcDistance = newLatLng => {
const { prevLatLng } = this.state;
return haversine(prevLatLng, newLatLng) || 0;
};
componentWillUnmount() {
clearInterval(this.interval);
navigator.geolocation.clearWatch(this.watchID);
}
render() {
const { data, isLoading } = this.state;
return (
<View style={{ flex: 1, width: "100%" }}>
<CustomHeader title="Track Route" navigation={this.props.navigation} />
{isLoading ? (
<ActivityIndicator />
) : (
<FlatList
data={data}
keyExtractor={(id, index) => index.toString()}
renderItem={({ item }) => (
<Display1
value1={item.field1}
value2={item.field2}
value3={item.field3}
value4={this.state.userLat}
value5={this.state.userLng}
/>
)}
/>
)}
</View>
);
}
}
const styles = StyleSheet.create({
appButtonText: {
fontSize: 18,
color: "#fff",
fontWeight: "bold",
alignSelf: "center",
textTransform: "uppercase",
},
});
Dispaly.js
import React, { Component } from "react";
import {
StyleSheet,
View,
Text,
TouchableOpacity,
Platform,
Dimensions,
Image,
} from "react-native";
import * as Location from 'expo-location';
import MapView, {
PROVIDER_GOOGLE,
Marker,Polyline,
AnimatedRegion,
} from "react-native-maps";
import AutoScrolling from "react-native-auto-scrolling";
import { getPreciseDistance } from 'geolib';
const { width, height } = Dimensions.get("window");
export default class Map extends Component {
// constructor(props) {
// super(props);
// this.state = {
// };
// }
constructor(props) {
super(props);
this.marker = null;
this.timeout = null;
this.state = {
isMapReady: false,
userLat: 0,
userLng: 0,
Time:0,
Dis: 0,
hasLocationPermissions: false,
locationResult: null,
coordinate: new AnimatedRegion({
latitude: parseFloat(this.props.value1),
longitude: parseFloat(this.props.value2),
latitudeDelta: 0.05,
longitudeDelta: 0.04,
}),
};
}
async componentDidMount() {
this.mounted = true;
this.timeout = setTimeout(()=>{ var pdis = getPreciseDistance(
{latitude:parseFloat(this.props.value1), longitude: parseFloat(this.props.value2)},
{latitude: parseFloat(this.props.value4), longitude: parseFloat(this.props.value5)},
);
// console.log(
// `Precise Distance\n\n${pdis} Meter\nOR\n${pdis / 1000} KM`
// );
this.setState({Dis:pdis,Time:Math.round( pdis/(this.props.value3*1000) )})} ,2000)
this.setState({
Time:this.state.Time.toFixed(2)
})
}
componentWillUnmount = () =>{
this.mounted = false;
if (this.timeout) {
clearTimeout(this.timeout)
}
}
onMapLayout = () => {
this.setState({ isMapReady: true });
};
render() {
// console.log( this.state.userLat,
// this.state.userLng,"myConsole")
return (
<View>
{this.state.Dis !== 0 ?
<View style={{backgroundColor:"rgba(52, 52, 52, 0.00006)"}}>
<Text style={{ color: "green", fontWeight: "bold", marginTop: 10, alignSelf: "center", marginBottom: 3, }}>Bus is {this.state.Dis / 1000} km Away.</Text>
<AutoScrolling style={{ backgroundColor: "rgba(52, 52, 52, 0.00006)",
width: 400,
padding: 10,
marginBottom: 10,}} endPadding={50}>
<Text style={ {
color: "red",
fontSize: 20,
fontWeight: "bold",
textAlign: "center",
margin: 5,
}}>Bus is Coming in {this.state.Time} Minutes</Text>
</AutoScrolling>
</View>
:null }
<MapView
initialRegion={{
latitude: parseFloat(this.props.value1),
longitude: parseFloat(this.props.value2),
latitudeDelta: 0.02,
longitudeDelta: 0.01,
}}
onMapReady={this.onMapLayout}
provider={PROVIDER_GOOGLE}
loadingIndicatorColor="#e21d1d"
ref={(map) => (this.map = map)}
style={{
width,height
}}
loadingEnabled={true}
>
{this.state.isMapReady && (
<MapView.Marker
key="AIzaSyB8k3Irk81q1k8pbj5tPM33KRWNdtROoOg"
identifier="marker"
coordinate={{
latitude: parseFloat(this.props.value1),
longitude: parseFloat(this.props.value2),
}}
flat={false}
title="Route 1"
description = "Driver: Muhammad Murtaza"
>
<Image source={require("D:/React Native apps/Bus-Track1-main/assets/car-marker.png")} style={{ width: 60, height: 50 }}/>
</MapView.Marker>
)}
<MapView.Marker
key="AIzaSyArnXt8Xqydc3BF9Udt8JCkFuKqgPR_HM0"
identifier="marker1"
coordinate={{
latitude: parseFloat(this.props.value4),
longitude: parseFloat(this.props.value5)
}}
title="My Location"
/>
<Polyline
coordinates={[
{ latitude: parseFloat(this.props.value4),
longitude: parseFloat(this.props.value5)
},
{ latitude: parseFloat(this.props.value1),
longitude: parseFloat(this.props.value2)
},
]}
strokeColor="red"
strokeColors={[
'#238C23',
'red'
]}
strokeWidth={5}
/>
</MapView>
</View>
);
}
}
I have two-component classes. First is TrackRoute1.js from which I'm passing bus location parameters and also user current location parameters to class Dispaly.js through the server. But after displaying I keep getting a memory leak that indicates that it cant perform react state update on an unmounted component. I tried everything. But it won't help.!