我试图为我的训练构建一个气象应用程序,但是我遇到了问题。
无论做什么我都会遇到类型错误。我打算做的是从Weathermap API获取json数据,然后
显示一些字符串,但我不能。
这是“我的应用”中的主要内容
import React, { Component } from 'react';
import { View, StyleSheet, Text } from 'react-native';
class Content extends Component{
constructor(props) {
super(props);
this.state = {
data: this.props.weather.main,
};
}
render() {
return (
<View style={styles.content}>
<Text style={styles.city}>City Name</Text>
<Text style={styles.itemsize}>Weather {this.state.data}</Text>
<Text style={styles.itemsize}>Description</Text>
<Text style={styles.itemsize}>Temperature Celsius</Text>
<Text style={styles.itemsize}>Pressure</Text>
<Text style={styles.itemsize}>Humidity</Text>
</View>
);
}
}
const styles = StyleSheet.create({
content: {
flex: 1,
justifyContent: 'center',
alignItems:'center'
},
city: {
fontSize: 50,
padding: 20
},
itemsize: {
fontSize: 30,
padding: 5
}
})
export default Content;
这是我的上层组件,正在尝试获取数据并传递下去。
import React, { Component } from 'react';
import Content from './Content';
import GetWeather from './GetWeather';
class Home extends Component {
constructor(props) {
super(props);
this._getData.bind(this);
this._getData();
this.state = {
data: null,
};
}
_getData = () => {
GetWeather.getWeather().then( json => {
console.log(json);
this.setState({data: json});
});
};
render() {
return (
<Content weather={this.state.data}/>
);
}
}
export default Home;
最后一个是我编写的用于从openweathermap获取api数据的代码
function getLocation(lat, long) {
return `${API_STEM}lat=${lat}&lon=${long}&appid=${APP_ID}`;
}
function getWeather() {
return fetch(getLocation(LATTITUDE,LONGGITUDE))
.then(response => response.json())
.then(responseJson => {
return { main: responseJson.weather[0].main};})
.catch(err =>console.log(err));
}
export default {getWeather: getWeather};
答案 0 :(得分:0)
在请求完成之前,您已经将this.state.data
内的Content
设置为null
,并且在重新渲染组件时它不会被更新,因为构造函数仅在安装时运行一次。
从state
设置props
是一种反模式,只应在极少数情况下使用。
相反,请从this.props
中读取天气数据,一旦父组件更新了其状态,该数据就会得到更新
在访问this.props.weather
内部的null
之前,您还需要检查.main
是否为this.props.weather
class Content extends Component {
render() {
const { weather } = this.props
return (
<View style={styles.content}>
<Text style={styles.city}>City Name</Text>
<Text style={styles.itemsize}>
Weather {weather ? weather.main : null}
</Text>
<Text style={styles.itemsize}>Description</Text>
<Text style={styles.itemsize}>Temperature Celsius</Text>
<Text style={styles.itemsize}>Pressure</Text>
<Text style={styles.itemsize}>Humidity</Text>
</View>
)
}
}
答案 1 :(得分:0)
主要问题是this.state.data
组件中的Home
是在创建Content
组件之后(在调用其constructor
函数之后)设置的。
这将生成一个TypeError
,因为this.props.weather
是undefined
,并且您正在尝试访问属性this.props.weather.main
。
解决此问题的最简单方法是直接使用props对象,而不是将这些props添加到状态,这是一个示例:
<Text style={styles.itemsize}>Weather {this.props.weather}</Text>
答案 2 :(得分:0)
在您的父组件中,状态永远不会获取数据,并且始终保持为空。当我们想从API获取数据时,应该使用称为componentDidMount()的react生命周期方法。因此,在父组件中,您应该在componentDidMount中调用_getdata函数,或者在生命周期方法中获取数据,例如下面的代码,这是我认为更好的方法。另外,永远不要将您的状态最初设置为null。将其设置为空对象。
import React, { Component } from 'react';
import Content from './Content';
import GetWeather from './GetWeather';
class App extends Component {
constructor(props) {
super(props);
this.state = {
data: {},
};
}
componentDidMount() {
GetWeather.getWeather().then( json => {
console.log(json);
this.setState({data: json});
});
}
render() {
console.log(this.state.data);
return (
<Content weather={this.state.data}/>
);
}
}
export default App
然后在子组件中,应该使用更新生命周期方法(有风险)之一,或者可以将子组件更改为功能组件,因为您不需要状态。
import React, { Component } from 'react';
import { View, StyleSheet, Text } from 'react-native';
function Content(props) {
return (
<View style={styles.content}>
<Text style={styles.city}>City Name</Text>
<Text style={styles.itemsize}>Weather {props.weather.main}</Text>
<Text style={styles.itemsize}>Description</Text>
<Text style={styles.itemsize}>Temperature Celsius</Text>
<Text style={styles.itemsize}>Pressure</Text>
<Text style={styles.itemsize}>Humidity</Text>
</View>
)
}
const styles = StyleSheet.create({
content: {
flex: 1,
justifyContent: 'center',
alignItems:'center'
},
city: {
fontSize: 50,
padding: 20
},
itemsize: {
fontSize: 30,
padding: 5
}
})
export default Content;