反应this.props未定义或空对象 [英] react this.props undefined or empty object

查看:166
本文介绍了反应this.props未定义或空对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

构建一个通过地理位置(由浏览器确定为props的子组件)的小型React应用.

Building a small react app that passes the geolocation (determined by the browser to a child component as props).

第一个组件:App.jsx

The first component: App.jsx

import React, {Component} from 'react';

import DateTime from './components/dateTime/_dateTime.jsx';
import Weather from './components/weather/_weather.jsx';
import Welcome from './components/welcome/_welcome.jsx';

require ('../sass/index.scss');

export default class App extends Component {

  constructor() {
    super();
    this.state = {
      latitude: '',
      longitude: ''
    };
    this.showPosition = this.showPosition.bind(this);
  }

  startApp () {
    this.getLocation();
  }

  getLocation() {
    if (navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(this.showPosition);
    } else {
        console.log("Geolocation is not supported by this browser.");
    }
  }

  showPosition(position) {
    this.setState({
        latitude: position.coords.latitude,
        longitude: position.coords.longitude
    })
  }

  componentWillMount () {
    this.startApp();
  }

  render() {
    return (
        <div className="container">
            <div className="header-container">
                <Weather latitude={ this.state.latitude } longitude={ this.state.longitude } />
            <DateTime />
            </div>
            <div className="welcome-container">
                <Welcome name="Name" />
            </div>
      </div>
    );
  }
}

此组件确定位置,将经纬度保存为状态,并将此信息通过道具传递给Weather.jsx组件,如下面的图像所示,该组件正在工作:

This component determines the location, saves the latitude and longitude to state and passes this information via props to the Weather.jsx component, which is working as you can see in the below image:

然后在weather.jsx组件中,我尝试访问这些道具并获得未定义或空的对象.

And in the weather.jsx component I try and access these props and get either undefined or an empty object.

import React, {Component} from 'react';
import Fetch from 'react-fetch';

export default class Weather extends Component {

    constructor(props) {
        super(props);
        this.state = {
          forecast: {},
          main: {},
          weather: {},
        };
        this.setWeather = this.setWeather.bind(this);
    }

    getWeather (latitude, longitude) {
        var self = this;

        fetch('http://api.openweathermap.org/data/2.5/weather?lat=' + latitude + '&lon=' + longitude + '&units=metric&APPID=ed066f80b6580c11d8d0b2fb71691a2c')  
            .then (function (response) {  
                if (response.status !== 200) {  
                    console.log('Looks like there was a problem. Status Code: ' + response.status);  
                    return;  
                }

                response.json().then(function(data) {  
                    self.setWeather(data);
                });
            })

            .catch (function (err) {  
                console.log('Fetch Error :-S', err);  
            });
    }

    setWeather (forecast) {
        var main = forecast.main;
        var weather = forecast.weather[0];

        this.setState({
            main: main,
            weather: weather,
            forecast: forecast
        });
    }

    startApp () {
        this.getWeather(this.props.latitude, this.props.longitude);
    }

    componentWillMount () {
        this.startApp();
    }

    componentDidMount () {
        // window.setInterval(function () {
    //          this.getWeather();
    //  }.bind(this), 1000);
    }

  render() {
    return (
        <div className="">
            <div className="weather-data">
                <span className="temp">{Math.round(this.state.main.temp)}&#176;</span>
                <h2 className="description">{this.state.weather.description}</h2>
            </div>
        </div>
    )
  }
}

真的不知道问题出在哪里,因为react开发工具表明天气组件确实在道具中设置了位置,然后传递给该组件.

Really not sure what the issue is as the react dev tools shows that the weather component does indeed have the location set in the props which are passed down to that component.

编辑**已解决:

所以问题在于状态是异步设置的,而天气组件是在状态更新之前呈现的.

So the issue was that state is set asynchronously and that my weather component was rendered before state was updated.

在render方法期间对状态内的值进行简单检查即可解决此问题.

A simple check of the values within state during the render method solved the issue.

render() {

    if (this.state.latitude != '' && this.state.longitude != '') {
      var weatherComponent = <Weather latitude={ this.state.latitude } longitude={ this.state.longitude } />
    } else {
      var weatherComponent = null;
    }

    return (
        <div className="container">
            <div className="header-container">
                {weatherComponent}
            <DateTime />
            </div>
            <div className="welcome-container">
                <Welcome name="Name" />
            </div>
      </div>
    );
  }

推荐答案

我认为问题如下. SetState异步发生.因此,您的渲染函数会在纬度和经度道具具有数据之前触发.如果在渲染Weather组件之前进行了一些if检查,则可能不会出现此问题.这是我的意思的例子.

I believe the issue is as follows. SetState happens asynchronously. Because of this, your render function is firing before the latitude and longitude props have data. If you would have some if check before rendering your Weather component you would likely not have this issue. Here is an example of what I mean.

render() {
    let myComponent;
    if(check if props has val) {
        myComponent = <MyComponent />
    } else {
        myComponent = null
    }
    return (
        <div>
            {myComponent}
        </div>
    )
}

这篇关于反应this.props未定义或空对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆