Я пытаюсь реализовать поиск и определение местоположения в родном реагировании. Я использую пакеты react-native-maps
и react-native-google-places-autocomplete
для их очевидного использования.
Сначала я инициировал регион в состоянии как:
constructor(){
this.state = {
mapRegion: {
latitude: this.props.latitude ? this.props.latitude : 27.7172,
longitude: this.props.longitude ? this.props.longitude : 85.3240,
latitudeDelta: 0.005,
longitudeDelta: 0.005,
},
}
}
Я пытался обновить регион при нажатии на результаты автозаполнения поиска, а также при перетаскивании маркера. Но я получаю сообщение об ошибке:
Error: You attempted to set the key latitude with the value '27' on an object that is meant to be immutable and has been frozen.
Я реализовал код как:
<GooglePlacesAutocomplete
placeholder='Search'
fetchDetails = {true}
onPress = {(data, details = null) => {
let tempMapRegion = this.state.mapRegion;
tempMapRegion.latitude = details.geometry.location.lat;
tempMapRegion.longitude = details.geometry.location.lng;
this.setState({ mapRegion: tempMapRegion })
}}
query = {{
key: AppSettings.googleMapApiKey,
language: 'en',
}}
/>
<MapView
initialRegion = {{
latitude: this.props.latitude ? this.props.latitude : 27.7172,
longitude: this.props.longitude ? this.props.longitude : 85.3240,
latitudeDelta: 0.005,
longitudeDelta: 0.005,
}}
region = {this.state.mapRegion}
onRegionChange = {(e) => { this.onRegionChange(e) }}
style = {{ height: 300, width: 300 }}
>
<Marker draggable
coordinate = {this.state.mapRegion}
onDragEnd = {(e) => {
let tempMapRegion = this.state.mapRegion;
tempMapRegion.latitude = e.nativeEvent.coordinate.latitude
tempMapRegion.longitude = e.nativeEvent.coordinate.longitude
this.setState({ mapRegion: tempMapRegion })
}}
/>
</MapView>
onRegionChange
в MapView
работает плавно, и маркер автоматически перетаскивается в центр, но обратный процесс вызывает указанную выше ошибку.
Что вызывает эту ошибку и как мне обойти это?
<View style = {{ padding: 2, }}>
<GooglePlacesAutocomplete
placeholder='Search'
fetchDetails = {true}
onPress = {(data, details = null) => {
let tempMapRegion = this.state.mapRegion;
tempMapRegion.latitude = details.geometry.location.lat;
tempMapRegion.longitude = details.geometry.location.lng;
this.map.animateToRegion(this.newRegion(tempMapRegion));
this.setState({ address: data.description })
}}
query = {{
key: AppSettings.googleMapApiKey,
language: 'en',
}}
/>
</View>
<MapView
provider = {this.props.provider}
ref = {ref => { this.map = ref; }}
mapType = {MAP_TYPES.TERRAIN}
initialRegion = {this.state.mapRegion}
onRegionChangeComplete = {(e) => { this.onRegionChange(e) }}
style = {{ height: width, width: width, marginTop: -5 }}
>
<Marker draggable
coordinate = {this.state.mapRegion}
onDragEnd = {(e) => {
let tempMapRegion = this.state.mapRegion;
tempMapRegion.latitude = e.nativeEvent.coordinate.latitude
tempMapRegion.longitude = e.nativeEvent.coordinate.longitude
this.map.animateToRegion(this.newRegion(tempMapRegion));
// this.setState({ mapRegion: tempMapRegion })
}}
/>
</MapView>
Итак, что в основном делало это, так это использование свойства animateToRegion
представления карты. Он в основном анимирует вид на указанную область, а затем вызывает onRegionChange
. Я наткнулся на этот ответ несколько раз, но это не сработало. Как ни странно, это работает только в версии сборки, а не во время отладки, по крайней мере, на эмуляторе.
Спасибо https://stackoverflow.com/a/53836679/5379191 этому ответу за то, что он показал путь.
newRegion(tempMapRegion) {
return {
...this.state.mapRegion,
...this.regionCoordinate(tempMapRegion),
};
}
regionCoordinate(tempMapRegion) {
return {
latitude: tempMapRegion.latitude,
longitude: tempMapRegion.longitude,
};
}