Engin Yilmaz
Engin Yilmaz

Reputation: 391

React Native Maps. Google Map turns back to initial location after on region change complete

I want registered users listed with markers on the map where he/she can see nearby app users. The map show initial markers but I cannot see dynamically assigned markers besides the map stuck into its initial place. For example I drag the map to other locations when I finish dragging map, it turns back.

App.js

import React, { Component } from 'react';
import { Text, View, StyleSheet, Switch, Alert, AppRegistry } from 'react-native';
import MapView from 'react-native-maps';
import Fetchdata from './Fetchdata.js';

const styles = StyleSheet.create({
  container: {
    ...StyleSheet.absoluteFillObject,
    height: 400,
    width: 400,
    justifyContent: 'flex-end',
    alignItems: 'center',
  },
  map: {
    ...StyleSheet.absoluteFillObject,
  },
});

export default class Stage extends Component {
  render() {
    return (
      <View style ={styles.container}>
        <Fetchdata />
      </View>
    );
  }
}

FetchData.js

import React, { Component } from 'react'
import { Text, View, StyleSheet, Switch, Alert, AppRegistry} from 'react-native'
import MapView, {Marker} from 'react-native-maps';

const styles = StyleSheet.create({
  container: {
    ...StyleSheet.absoluteFillObject,
    height: 400,
    width: 400,
    justifyContent: 'flex-end',
    alignItems: 'center',
  },
  map: {
    ...StyleSheet.absoluteFillObject,
  },
});
export default class Fetchdata extends Component {
  constructor (props) {
    super(props);
  }
  state = {
      latitude: 3.148561,
      longitude: 101.652778,
      markers: [{
    title: 'hello',
    coordinates: {
      latitude: 3.148561,
      longitude: 101.652778
    },
      },
      {
    title: 'hello',
    coordinates: {
      latitude: 3.149771,
      longitude: 101.655449
    },
      }]
   };
   componentDidMount = () => {
     navigator.geolocation.getCurrentPosition(
      (position) => {
    this.setState({
      latitude: position.coords.latitude,
      longitude: position.coords.longitude,
      error: null,
    });

      },
      (error) => this.setState({ error: error.message }),
      { enableHighAccuracy: true, timeout: 20000, maximumAge: 1000 },
    );
   }
   onRegionChange (region) {
     fetch('https://isg.info.tr/query_maps.php' + '?latitude=' + this.state.latitude + '&longitude=' + this.state.longitude , {
    method: 'GET'
     })
     .then((response) => response.json())
     .then((responseJson) => {
       const newState = Object.assign({}, this.state);
       newState.markers.coordinates = responseJson;
       this.setState(newState);
       //Alert.alert(responseJson+ " ")
      //Alert.alert('https://isg.info.tr/query_maps.php' + '?latitude=' + this.state.latitude + '&longitude=' + this.state.longitude);
       //this.markers = responseJson;
    console.log(responseJson);
     })
     .catch((error) => {
    console.error(error);
     });
     //Alert.alert(responseJson);
   };
   render() {
      return (
      <View style={styles.container}>
      <MapView
      style={styles.map}
      region={{
        latitude: this.state.latitude,
        longitude: this.state.longitude,
        latitudeDelta: 0.015,
        longitudeDelta: 0.015,
      }}
      onRegionChangeComplete={this.onRegionChange.bind(this)}
      >
      {this.state.markers.map((marker, index) => (
        <MapView.Marker key={index} coordinate={marker.coordinates} title={marker.title} />
      ))}
    </MapView>
      </View>
      );
   }
}

Json file from the query on the main server

[{"latitude" : 40.3565,"longitude" : 27.9774},{"latitude" : 40.3471,"longitude" : 27.9598},{"latitude" : 40,"longitude" : 27.9708}]

Upvotes: 1

Views: 12215

Answers (2)

Ganda Rain Panjaitan
Ganda Rain Panjaitan

Reputation: 949

Try this, put your marker in center of map, when user move the map, get the last location with onRegionChangeComplete. You can read the concept from this link

https://alizahid.dev/blog/keep-marker-in-center-and-move-map-around-it

Upvotes: 0

Michael Cheng
Michael Cheng

Reputation: 10451

You are making a copy of your state in onRegionChange. That includes this.state.latitude and this.state.longitude which do not update at all when you do setState after your fetch call. Because of this, once setState executes, the map will "snap back" to whatever was last saved in your state.

One way to fix this is to update your region controlled state values with what is passed to onRegionChange like this (using your coding style):

.then((responseJson) => {
  const newState = Object.assign({}, this.state);
  newState.markers.coordinates = responseJson;
  newState.latitude = region.latitude;
  newState.longitude = region.longitude;
  this.setState(newState);
  console.log(responseJson);
})

Alternatively, update that part of your state first in case you are relying on having up-to-date region information (latitude, longitude) elsewhere in your code. Then call the fetch in the setState callback:

onRegionChange (region) {
  this.setState({
    latitude: region.latitude,
    longitude: region.longitude,
  }, () => {
    fetch('https://isg.info.tr/query_maps.php' + '?latitude=' + 
    // ...the rest of your fetch call code here as is...
  });
};

If it we me though, I would simply not make a wholesale copy of your state. It's not a very normal practice in React and is inefficient when dealing with lots of data in state. So instead, I'd probably opt to only update the part of state that needs to be updated (markers):

.then((responseJson) => {
  let markers = [...this.state.markers];
  markers.coordinates = responseJson;
  this.setState({ markers });
  console.log(responseJson);
})

Note that I'm not updating your latitude and longitude values stored in state because the MapView should work fine if all you do is set region once and then never update the values used by it. However, if that is your use case and you do not intend on ever controlling your region, I suggest using the initialRegion prop instead. It will lead to fewer errors like this in the future.

Upvotes: 3

Related Questions