我的React Component状态持续返回null对象

时间:2019-12-22 05:48:22

标签: javascript reactjs react-native

我试图为我的训练构建一个气象应用程序,但是我遇到了问题。

无论做什么我都会遇到类型错误。我打算做的是从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};

3 个答案:

答案 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.weatherundefined,并且您正在尝试访问属性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;