大家好,
我遇到了 Geolocation 的问题,我正在访问我的当前位置以使用Link API上的纬度和经度,但遇到了一些无法访问API的问题,结果是最初找不到JSON数据,当我测试它们时,我将其保存到单独的变量中,但无法正常工作,现在如何在获取API之前保存它们?
我的代码在这里:
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
}
});
答案 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>
);
}
}