Reputation: 391
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
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
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