在设置尝试useState反应本机映射后,无法设置对象状态



Hi我似乎无法使用useState钩子设置值,正如您在pickedLocation输出中看到的那样。当我控制台pickedLocation时,我得到的是初始值。此外,即使设置了初始值,我的地图也没有显示。在IOS上,根据我的isFetching状态,我的消息是"尚未选择地图",android有一个不同的地图错误Error using newLatLngBounds(...

我在这里尝试过答案:https://stackoverflow.com/a/54069332/2277245使用useEffect和spread运算符,但它们也不起作用。有人帮忙吗?感谢

import React, { useState, useEffect } from "react";
import {
Alert,
StyleSheet,
Text,
View,
ActivityIndicator,
Platform
} from "react-native";
import { useSelector } from "react-redux";
import MapView, { Marker } from "react-native-maps";
import Constants from "expo-constants";
import * as Location from "expo-location";
import * as Permissions from "expo-permissions";
import Colors from "../constants/Colors";
const MapScreen = props => {
const availableVenues = useSelector(state => state.cafes.availableVenues);
const [isFetching, setIsFetching] = useState(false); //spinner
const initialValues = {
latitude: 37.78,
longitude: -122.43,
latitudeDelta: 0.0922,
longitudeDelta: 0.0421
};
const [pickedLocation, setPickedLocation] = useState(initialValues);
const selectItemHandler = (id, title) => {
props.navigation.navigate("VenueDetail", {
venueId: id,
venueTitle: title
});
};
useEffect(() => {
if (Platform.OS === "android" && !Constants.isDevice) {
Alert.alert(
"Error",
"Oops, this will not work on Sketch in an Android emulator. Try it on your device!",
[
{
text: "Okay"
}
]
);
} else {
getLocationHandler();
}
}, []);
const verifyPermissions = async () => {
const result = await Permissions.askAsync(Permissions.LOCATION);
if (result.status !== "granted") {
Alert.alert(
"Insufficient Permissions",
"Sorry, we need location permissions to make this work!",
[
{
text: "Okay"
}
]
);
return false;
}
return true;
};
const getLocationHandler = async () => {
const hasPermission = await verifyPermissions();
if (!hasPermission) {
return;
}
try {
setIsFetching(true);
const location = await Location.getCurrentPositionAsync({
timeout: 5000
});
const result = {
latitude: location.coords.latitude,
longitude: location.coords.longitude,
latitudeDelta: 0.1,
longitudeDelta: 0.1
};
setPickedLocation({...pickedLocation,...result});
console.log(pickedLocation); //Showing initial values
} catch (err) {
Alert.alert("Could Not Fetch Location", "Please Try again", [
{
text: "Okay"
}
]);
}
setIsFetching(false);
};
return (
<View style={styles.mapContainer}>
{isFetching ? (
<ActivityIndicator color={Colors.greenPrimary} size="large" />
) : (
<Text>No map chosen yet!</Text>
)}
<MapView
style={styles.map}
showsUserLocation={true}
initialRegion={pickedLocation}
region={pickedLocation}
>
{availableVenues.map(marker => (
<Marker
key={marker.id}
coordinate={{ latitude: marker.lat, longitude: marker.lng }}
title={marker.title}
description={marker.address}
onPress={() => {
selectItemHandler(marker.id, marker.title);
}}
/>
))}
</MapView>
</View>
);
};
MapScreen.navigationOptions = {
headerTitle: "Map of Venues"
};
const styles = StyleSheet.create({
mapContainer: {
flex: 1,
justifyContent: "center",
alignItems: "center"
},
map: {
justifyContent: "center",
alignItems: "center"
}
});
export default MapScreen;

我通过复制和改编官方expo文档中的示例解决了这个问题https://docs.expo.io/versions/v35.0.0/sdk/location/

import React, { useState, useEffect } from "react";
import { StyleSheet, Platform } from "react-native";
import { useSelector } from "react-redux";
import MapView, { Marker } from "react-native-maps";
import Constants from "expo-constants";
import * as Location from "expo-location";
import * as Permissions from "expo-permissions";
const MapScreen = props => {
const availableVenues = useSelector(state => state.cafes.availableVenues);
const [isLocation, setLocation] = useState(null);
const [mapRegion, setMapRegion] = useState({
region: {
latitude: -37.813629,
longitude: 144.963058,
latitudeDelta: 0.0922,
longitudeDelta: 0.0421
}
});
const selectItemHandler = (id, title) => {
props.navigation.navigate("VenueDetail", {
venueId: id,
venueTitle: title
});
};
useEffect(() => {
if (Platform.OS === "android" && !Constants.isDevice) {
Alert.alert(
"Error",
"Oops, this will not work on Sketch in an Android emulator. Try it on your device!",
[
{
text: "Okay"
}
]
);
} else {
this._getLocationAsync();
}
}, []);
_getLocationAsync = async () => {
let { status } = await Permissions.askAsync(Permissions.LOCATION);
if (status !== "granted") {
Alert.alert(
"Insufficient Permissions",
"Sorry, we need location permissions to make this work!",
[
{
text: "Okay"
}
]
);
}
let location = await Location.getCurrentPositionAsync({});
setLocation({ location });
setMapRegion({
region: {
latitude: location.coords.latitude,
longitude: location.coords.longitude,
latitudeDelta: 0.0922,
longitudeDelta: 0.0421
}
});
console.log(mapRegion);
};
return (
<MapView
style={styles.map}
showsUserLocation={true}
initialRegion={mapRegion.region}
region={mapRegion.region}
>
{availableVenues.map(marker => (
<Marker
key={marker.id}
coordinate={{ latitude: marker.lat, longitude: marker.lng }}
title={marker.title}
description={marker.address}
onPress={() => { //Need to change to press popup
setTimeout(() => {
selectItemHandler(marker.id, marker.title);
}, 5000);
}}
/>
))}
</MapView>
);
};
MapScreen.navigationOptions = {
headerTitle: "Venue Map"
};
const styles = StyleSheet.create({
map: {
flex: 1,
justifyContent: "center",
alignItems: "center"
},
container: {
flex: 1,
alignItems: "center",
justifyContent: "center",
paddingTop: Constants.statusBarHeight,
backgroundColor: "#ecf0f1"
},
paragraph: {
margin: 24,
fontSize: 18,
textAlign: "center",
color: "black"
}
});
export default MapScreen;

最新更新