现在正确,我遇到了react-native-maps
到expo
和redux
onRegionChange / onRegionChangeComplete 道具行为迟钝且不稳定,我无法找出原因。
我已经录制了3段非常短的视频,我希望你能看到,你会 了解所有这些。
您可以在此处看到此行为:https://youtu.be/HvKiC838ZiQ
我怎么到这里来?后续。
首先,我想创建一个允许我实现3件事的组件:
为实现这一目标,我决定从第2点开始。 3,一旦完成,询问位置。
所以我写了这个:
这是汇总的redux组件状态:
const INITIAL_STATE = {
initialRegion: {
latitude: 3.4562823396110987,
longitude: -76.53087161634343,
longitudeDelta: 0.020077778360303,
latitudeDelta: 0.02730640974786524,
},
region: {
latitude: null,
longitude: null,
longitudeDelta: null,
latitudeDelta: null
},
}
这是我写过的mapComponent:
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { View, TouchableOpacity, Image, Platform, Constants } from 'react-native';
import { Ionicons } from '@expo/vector-icons';
import { MapView, Location, Permissions } from 'expo';
import { setCurrentLocation, handlerRegion } from '../actions';
class Map extends Component {
renderMarker = () => {
if (this.props.direccion) {
return (
<MapView.Marker
draggable
coordinate={this.props.direccion}
>
<Image
source={require('../images/LocationIcon.png')}
style={{ width: 37, height: 56 }}
/>
</MapView.Marker>
);
}
}
render() {
const { mapStyle, buttonContainerStyle, trashButtonStyle } = styles;
const TrashButton = (props) => {
if (this.props.polygon.length > 0) {
return (
<TouchableOpacity onPress={props.trash}>
<View style={trashButtonStyle}>
<Ionicons name="ios-trash" size={35} color="#eb4050" />
</View>
</TouchableOpacity>
);
}
return null;
};
return (
<View style={{ flex: 1 }}>
<MapView
style={mapStyle}
initialRegion={this.props.initialRegion}
onPress={this.props.onPress}
onLongPress={this.props.onLongPress}
>
<MapView.Polygon
coordinates={this.props.polygon}
fillColor="rgba(235, 64, 80, 0.5)"
strokeColor="rgba(235, 64, 80, 1)"
holes={this.props.holes}
geodesic
lineDashPhase={6}
strokeWidth={2}
/>
{this.renderMarker()}
</MapView>
<View style={buttonContainerStyle}>
<TrashButton trash={this.props.trashButton} />
</View>
</View>
);
}
}
const styles = {
//Extracted for conciseness
};
const mapStateToProps = state => {
return {
polygon: state.perfil.polygon,
region: state.perfil.region,
direccion: state.perfil.direccion,
initialRegion: state.perfil.initialRegion
};
};
export default connect(mapStateToProps, { setCurrentLocation, handlerRegion })(Map);
这是parentComponent,它具有设置标记,多边形等方法:
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { View } from 'react-native';
import { MapView } from 'expo';
import { Header } from '../common';
import {
setRestaurantLocation,
setPolygonPoint,
setHoles,
eraseDeliveryArea,
saveRestaurantAddress,
setCurrentLocation,
handlerRegion
} from '../actions';
import Maps from './Maps';
class DireccionRestaurant extends Component {
static navigationOptions = {
drawerLockMode: 'locked-closed',
}
saveRestaurantAddressHandler = () => {
const { direccion, polygon, user } = this.props;
this.props.saveRestaurantAddress(direccion, polygon, user);
this.props.navigation.goBack();
}
setRestaurantLocationHandler = (latLng) => {
if (!this.props.direccion) {
this.props.setRestaurantLocation(latLng);
}
}
setPolygonPointHandler = (latLng) => {
if (this.props.direccion) {
this.props.setPolygonPoint(latLng);
}
}
setHolesHandler = (latLng) => {
console.log('this is the obj: ', latLng);
this.props.setHoles(latLng);
}
eraseDeliveryAreaHandler = () => {
this.props.eraseDeliveryArea();
}
render() {
const { navigation } = this.props;
return (
<View style={{ flex: 1 }}>
<Header title="Direccion" type="back" button="Guardar" onPress={() => this.saveRestaurantAddressHandler()} backLink={() => navigation.goBack()} />
<Maps
onPress={(e => this.setPolygonPointHandler(e.nativeEvent.coordinate))}
onLongPress={(e => this.setRestaurantLocationHandler(e.nativeEvent.coordinate))}
trashButton={() => this.eraseDeliveryAreaHandler()}
/>
</View
);
}
}
const mapStateToProps = state => {
return {
polygon: state.perfil.polygon,
holes: state.perfil.holes,
direccion: state.perfil.direccion,
user: state.auth.user,
region: state.perfil.region,
};
};
export default connect(mapStateToProps, {
setPolygonPoint,
setHoles,
setRestaurantLocation,
eraseDeliveryArea,
saveRestaurantAddress,
setCurrentLocation,
handlerRegion
})(DireccionRestaurant);
通过此设置,我实现了第2点和第2点。 3。 你可以在这里看到:
https://www.youtube.com/watch?v=W7f8wpkiYjo
好的,现在所有人似乎都按预期工作了,我微笑着去寻找1个目标:询问设备位置......
我决定使用AirBNB的expo
react-native-maps
实现,所以我将此道具添加到我的Maps.js组件中:
//class Map extends Component {
getLocationAsync = async () => {
// let { status } = await Permissions.askAsync(Permissions.LOCATION);
//if (status !== 'granted') {
// this.setState({
// errorMessage: 'Permission to access location was denied',
// });
// }
let location = await Location.getCurrentPositionAsync({});
const latitude = location.coords.latitude;
const longitude = location.coords.longitude;
this.props.setCurrentLocation(latitude, longitude);
console.log('this is the latitude mounted: ', latitude, '- this the longitude: ', longitude);
};
//...
我还写了生命周期方法:
//class Map extends Component {
//...
componentWillMount() {
this.getLocationAsync();
}
//...
因此,当componentWillMount请求位置并使用此流程将位置设置为新状态时:
动作
export const setCurrentLocation = (latitude, longitude) => {
const newState = {
latitude,
longitude,
latitudeDelta: 0.026541072889699535,
longitudeDelta: 0.019344975439523182,
};
return {
type: SET_ACTUAL_LOCATION,
payload: newState
};
};
减速
case SET_ACTUAL_LOCATION:
return { ...state, region: action.payload };
并更新了地图组件:
<MapView
style={mapStyle}
initialRegion={this.props.initialRegion}
region={this.props.region}// <--- Added this
onPress={this.props.onPress}
onLongPress={this.props.onLongPress}
>
万岁!位置正在工作,让我们添加标记......什么?...发生了什么?好吧,也许只是我。让我们尝试创建多边形......什么?它又发生了!
观看此视频,了解发生了什么:https://youtu.be/RlKZvBTVXa0
我想:
哦! ,这似乎是由于没有onRegionChange引起的 方法,因为当我把一个新的标记或添加一个新的点,所以 组件重新呈现与存储在其上的最后一个区域 州。好的,所以我会添加一个onRegionChangeComplete,因为它适合 更符合我的需求。
现在我将它添加到Maps.js组件:
<MapView
style={mapStyle}
initialRegion={this.props.initialRegion}
region={this.props.region}
onPress={this.props.onPress}
onLongPress={this.props.onLongPress}
onRegionChangeComplete={(region) => this.props.handlerRegion(region)}//<-ADDED THIS
>
并编写以下redux流程:
动作:
export const handlerRegion = (region) => {
return {
type: HANDLE_CHANGE_REGION,
payload: region
};
};
减速
case HANDLE_CHANGE_REGION:
return { ...state, region: action.payload };
Aaaaaand ......结果是在第一个视频中发生了什么。 这是视频 - &gt;:https://youtu.be/HvKiC838ZiQ
该组件完全正常工作。现在存储在状态中的最后一个区域与我们搜索的位置相同,所以当我添加一个标记或多边形的点时,它仍然保留在应该的位置。 剩下的唯一问题是你可以看到的滞后和奇怪的行为......
我认为它可能是由redux引起的,所以我尝试使用reactComponent的状态,但它也发生了。
我尝试使用onRegionChange和onRegionChangeComplete,但它几乎相同。
我用同样的问题搜寻了其他人,但我没有找到任何问题。
我无法弄清楚为什么会这样。 你知道为什么吗?
答案 0 :(得分:0)
将initialRegion
设置为MapView
并删除region = {this.state.region}
对我来说解决了类似的问题。