【问题标题】:Cannot set object state after set attempt useState react native maps设置尝试后无法设置对象状态 useState 反应原生地图
【发布时间】:2020-02-27 12:34:31
【问题描述】:

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

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

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;

【问题讨论】:

    标签: javascript react-native react-hooks


    【解决方案1】:

    我通过复制和改编官方博览会文档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;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-30
      • 1970-01-01
      • 1970-01-01
      • 2020-02-22
      • 2021-05-28
      • 1970-01-01
      相关资源
      最近更新 更多