在React Native中获取API之前如何保存当前位置的经纬度坐标?

时间:2018-12-16 17:22:14

标签: javascript android reactjs google-maps react-native

大家好,

我遇到了 Geolocation 的问题,我正在访问我的当前位置以使用Link API上的纬度和经度,但遇到了一些无法访问API的问题,结果是最初找不到JSON数据,当我测试它们时,我将其保存到单独的变量中,但无法正常工作,现在如何在获取API之前保存它们?

Error

我的代码在这里:

    import React, { Component } from "react";
    import {
      StyleSheet,
      Text,
      View,
      TextInput,
      ScrollView,
      Image,
      ActivityIndicator
    } from "react-native";
    import Icon from "react-native-vector-icons/dist/FontAwesome";


    export default class App extends Component {
      constructor(props) {
        super(props);
        this.state = {
          isLoading: true,
          dataSource: [],
          latitude: null,
          longitude: null,
          error: null
        };
      }
      async componentDidMount() {
        this.watchId = navigator.geolocation.watchPosition(
          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,
            distanceFilter: 5
          }
        );
    var myLat = `${this.state.latitude}`;
        var myLon = `${this.state.longitude}`;
     let API_WEATHER = `http://api.openweathermap.org/data/2.5/weather?lat=${myLat}&lon=${myLon}&units=metric&appid=${API_KEY}`;

fetch(API_WEATHER)
      .then(response => response.json())
      .then(responseJson => {
        console.log(responseJson);
        console.log(responseJson.weather);
        this.setState({
          isLoading: false,
          dataSource: responseJson
        });
      })
      .catch(error => {
        console.log(error);
      });
  }

render() {
    if (this.state.isLoading) {
      return (
        <View style={{ flex: 1, padding: 20 }}>
          <ActivityIndicator size="large" />
        </View>
      );
    }
 var icon =
      this.state.dataSource.main.temp <= 20
        ? require("./assets/cloudySun.png")
        : require("./assets/sunny.png");
    return (
      <ScrollView style={styles.container}>
        <View style={styles.head}>
          <Text style={styles.titleApp}>Weather App</Text>
          <View
            style={{
              flexGrow: 1,
              alignItems: "center",
              justifyContent: "center"
            }}
          >
            <Text>Latitude: {this.state.latitude}</Text>
            <Text>Longitude: {this.state.longitude}</Text>
            {this.state.error ? <Text>Error: {this.state.error}</Text> : null}
          </View>
        </View>
        <View style={styles.defaultWeather}>
          <View style={styles.infoDegree}>
            <Text style={{ fontSize: 80, color: "#42434B", paddingBottom: 0 }}>
              {this.state.dataSource.main.temp}°
            </Text>
            <Text style={{ fontSize: 16, padding: 7 }}>
              {this.state.dataSource.name},{this.state.dataSource.sys.country}
            </Text>
            <Text style={{ color: "#42434B", fontSize: 20, padding: 2 }}>
              {this.state.dataSource.weather[0].description}
            </Text>
          </View>
 var icon =
      this.state.dataSource.main.temp <= 20
        ? require("./assets/cloudySun.png")
        : require("./assets/sunny.png");
    return (
      <ScrollView style={styles.container}>
        <View style={styles.head}>
          <Text style={styles.titleApp}>Weather App</Text>
          <View
            style={{
              flexGrow: 1,
              alignItems: "center",
              justifyContent: "center"
            }}
          >
            <Text>Latitude: {this.state.latitude}</Text>
            <Text>Longitude: {this.state.longitude}</Text>
            {this.state.error ? <Text>Error: {this.state.error}</Text> : null}
          </View>
        </View>
        <View style={styles.defaultWeather}>
          <View style={styles.infoDegree}>
            <Text style={{ fontSize: 80, color: "#42434B", paddingBottom: 0 }}>
              {this.state.dataSource.main.temp}°
            </Text>
            <Text style={{ fontSize: 16, padding: 7 }}>
              {this.state.dataSource.name},{this.state.dataSource.sys.country}
            </Text>
            <Text style={{ color: "#42434B", fontSize: 20, padding: 2 }}>
              {this.state.dataSource.weather[0].description}
            </Text>
          </View>
         </View>
</ScrollView>



const styles = StyleSheet.create({
  container: {
    flex: 1,
    padding: 5,
    backgroundColor: "#F2F4FA"
  },
  head: {
    alignItems: "center"
  },
  titleApp: {
    fontSize: 20,
    fontWeight: "400",
    color: "#000"
  },
  defaultWeather: {
    flexDirection: "row",
    justifyContent: "space-between"
  },
  infoDegree: {
    padding: 15,
    marginBottom: 20
  },
  searchSection: {
    marginBottom: 50,
    flexDirection: "row",
    justifyContent: "center",
    alignItems: "center",
    backgroundColor: "#fff",
    shadowColor: "#eee",
    shadowOffset: { width: 10, height: 3 },
    shadowOpacity: 0.8,
    shadowRadius: 10,
    elevation: 5
  },
  searchIcon: {
    padding: 10
  },
  input: {
    flex: 1,
    paddingTop: 10,
    paddingRight: 10,
    paddingBottom: 10,
    paddingLeft: 0,
    backgroundColor: "#fff",
    color: "#424242"
  },
  statusWeather: {
    width: 210,
    padding: 20,
    margin: 10,
    backgroundColor: "#e8ebf7"
  },
  ImgWeek: {
    marginTop: 10,
    marginBottom: 23
  },
  TextStatus: {
    color: "#607498",
    fontSize: 17,
    padding: 10
  }
});

2 个答案:

答案 0 :(得分:1)

尝试以下操作,将回调传递给setState,在那里您将获得新的经度,很长:

  componentDidMount() {
            this.watchId = navigator.geolocation.watchPosition(
              position => {
                this.setState({
                  latitude: position.coords.latitude,
                  longitude: position.coords.longitude,
                  error: null
                },()=>{
        var myLat = `${this.state.latitude}`;
            var myLon = `${this.state.longitude}`;
         let API_WEATHER = `http://api.openweathermap.org/data/2.5/weather?lat=${myLat}&lon=${myLon}&units=metric&appid=${API_KEY}`;

    fetch(API_WEATHER)
          .then(response => response.json())
          .then(responseJson => {
            console.log(responseJson);
            console.log(responseJson.weather);
            this.setState({
              isLoading: false,
              dataSource: responseJson
            });
          })
          .catch(error => {
            console.log(error);
          });

});
              },
              error => this.setState({ error: error.message }),
              {
                enableHighAccuracy: true,
                timeout: 20000,
                maximumAge: 1000,
                distanceFilter: 5
              }
            );

      }

答案 1 :(得分:0)

我对您的代码做了一些性能。我希望这会有所帮助。

import React, { Component } from "react";
import {
  StyleSheet,
  Text,
  View,
  TextInput,
  ScrollView,
  Image,
  ActivityIndicator
} from "react-native";

import Icon from "react-native-vector-icons/dist/FontAwesome";


export default class App extends Component {

  constructor(props) {
    super(props);
    this.ApiKeyRef = 'hdjdjdjjd555555555555'

    this.watchPositionOpts = {
      enableHighAccuracy: true,
      timeout: 20000,
      maximumAge: 1000,
      distanceFilter: 5
    }
    this.state = {
      isLoading: true,
      dataSource: [],
      latitude: null,
      longitude: null,
      error: null
    };
  }

  componentDidMount() {
    this.watchId = navigator.geolocation.watchPosition(
      this.watchPositionSuccess, this.watchPositionFail, this.watchPositionOpts 
    );              
  }     

  componentWillUnmount(){
    //dont forget to clear
    navigator.geolocation.clearWatch(this.watchId);
    navigator.geolocation.stopObserving();
  }           

  watchPositionSuccess = (position) => {
    this.setState({ 
      latitude: position.coords.latitude, 
      longitude: position.coords.longitude, 
      error: null
    }, () => this.fetchCallback());
  }

  watchPositionFail = (err) => {
    this.setState({ error: err.message })
  }

  fetchCallback = () => {
    const { latitude, longitude } = this.state
    const req = `http://api.openweathermap.org/data/2.5/weather?lat=${latitude}&lon=${longitude}&units=metric&appid=${this.ApiKeyRef}`;
    const callback = (responseJson) => {
      console.log(responseJson)
      console.log(responseJson.weather)
    }

    fetch(req)
      .then(response => response.json())
      .then(responseJson => this.setState({ isLoading: false, dataSource: responseJson}, ()=> callback(responseJson)))
      .catch(error => console.log(error))      
  }

  render() {

      const { 
        isLoading, 
        dataSource, 
        error, 
        latitude, 
        longitude 
      } = this.state; 

      if (isLoading) {
        return (
          <View style={{ flex: 1, padding: 20 }}>
            <ActivityIndicator size="large" />
          </View>
        );
      }

      const icon = dataSource.main.temp <= 20 ? require("./assets/cloudySun.png") : require("./assets/sunny.png")

      return (
          <ScrollView style={styles.container}>
            <View style={styles.head}>
              <Text style={styles.titleApp}>Weather App</Text>
              <View style={{ flexGrow: 1, alignItems: "center", justifyContent: "center" }}>
                <Text>Latitude: {latitude}</Text>
                <Text>Longitude: {longitude}</Text>
                {error && <Text>Error: {error}</Text>}
              </View>
            </View>
            <View style={styles.defaultWeather}>
              <View style={styles.infoDegree}>
                <Text style={{ fontSize: 80, color: "#42434B", paddingBottom: 0 }}>
                  {dataSource.main.temp}°
                </Text>
                <Text style={{ fontSize: 16, padding: 7 }}>
                  {dataSource.name},{dataSource.sys.country}
                </Text>
                <Text style={{ color: "#42434B", fontSize: 20, padding: 2 }}>
                  {dataSource.weather[0].description}
                </Text>
              </View>
            </View>
          </ScrollView>
      );
    }
  }