I am currently attempting to make an app with one screen where the background of the screen is taken up by a map centered on the user's current coordinates. In the below code, I have saved the longitude and longitude as null within the state of the App class component. Then, I use the inherited method 'componentDidMount()' to update the state with the user's current location, and finally in render() I use this.state.latitude and this.state.longitude to inform the values for latitude and longitude for MapView.
The code does not compile. Using console.log, I have isolated the problem to be that render() is being called twice, and my console.log statement first outputs the null value to the console, and then outputs the user's current location.
So two questions.
1) Why does console.log output values to the console two different times, one of which is the state value passed in and one of which is the state value updated by componentDidMount()?
2) How can I run the function navigator.geolocation.getCurrentPosition() to save the user's current location and pass it to MapView so that the code compiles in the first place?
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = { latitude: null, longitude: null };
}
componentDidMount() {
navigator.geolocation.getCurrentPosition(position => {
this.setState({
latitude: position.coords.latitude,
longitude: position.coords.longitude,
});
});
}
render() {
return (
<View style={styles.container}>
<MapView
style={styles2.map}
initialRegion={{
latitude: this.state.latitude,
longitude: this.state.longitude,
latitudeDelta: 0.0922,
longitudeDelta: 0.0421,
}}
/>
{console.log(this.state.latitude)}
{console.log(this.state.longitude)}
</View>
);
}
}
React will re-render whenever your component updates via state or props. In your componentDidMount() you are calling setState(), so at some point after that (since it is asynchronous), your component will need to update for the new state so it renders again.
The first render() occurs when your component mounts. This is where you will see whatever the initial values of latitude and longitude are on your state.
After your component has mounted, your call to setState() will update state with the new values of latitude and longitude so your component will render() a second time where you will see the new values of latitude and longitude.
EDIT:
If you want to avoid the first display of latitude and longitude (NB. It will still render twice) you could conditionally render i.e.
render() {
if(!this.state.longitude) {
return <View>Loading...</View>;
}
return (
<View style={styles.container}>
<MapView
style={styles2.map}
initialRegion={{
latitude: this.state.latitude,
longitude: this.state.longitude,
latitudeDelta: 0.0922,
longitudeDelta: 0.0421,
}}
/>
</View>
);
}
The render method is called always that a value from state or props is changed
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With