wake-up-neo.net

reagieren Sie dies.props undefiniertes oder leeres Objekt

Erstellen einer kleinen Reaktions-App, die die Geolocation (vom Browser an eine untergeordnete Komponente als Requisiten übergeben) übergibt.

Die erste Komponente: 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>
    );
  }
}

Diese Komponente bestimmt den Standort, speichert die geografischen Breiten- und Längengrade und gibt diese Informationen über Requisiten an die Komponente Weather.jsx weiter, die wie in der folgenden Abbildung dargestellt funktioniert:

 enter image description here

Und in der weather.jsx-Komponente versuche ich, auf diese Requisiten zuzugreifen und bekomme entweder ein undefiniertes oder ein leeres Objekt.

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>
    )
  }
}

Wirklich nicht sicher, was das Problem ist, da die reaktiven Entwicklungswerkzeuge zeigen, dass die Wetterkomponente tatsächlich die Position in den Requisiten aufweist, die an diese Komponente weitergegeben werden.

Bearbeiten ** Gelöst:

Das Problem war also, dass der Status asynchron gesetzt wurde und dass meine Wetterkomponente gerendert wurde, bevor der Status aktualisiert wurde.

Eine einfache Überprüfung der Werte innerhalb des Zustands während der Rendermethode löste das Problem.

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>
    );
  }
13
chinds

Ich glaube, das Problem ist wie folgt. SetState geschieht asynchron. Aus diesem Grund wird Ihre Renderfunktion ausgelöst, bevor die Längen- und Breitengradeigenschaften Daten haben. Wenn Sie vor dem Rendern Ihrer Weather-Komponente eine Prüfung hätten, hätten Sie wahrscheinlich dieses Problem nicht. Hier ist ein Beispiel von dem, was ich meine.

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

Sie müssen startApp() und getWeather() an die Komponente binden, andernfalls wäre thisundefined.

export default class Weather extends Component {

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

Sie müssen so viel wie sauber rendern. Vermeiden Sie if if else in render stattdessen, wenn else direkt mit dem ternären Operator oder dem Operator && prüft. Führen Sie die bedingte Überprüfung wie unten beschrieben aus und rufen Sie dann MyComponent wie unten beschrieben auf

render() {
    return (
        <div>
            {this.state.latitude != '' && this.state.longitude != '' ? <Weather latitude={ this.state.latitude } longitude={ this.state.longitude } />: null}
            {this.state.latitude != '' && this.state.longitude != '' && <Weather latitude={ this.state.latitude } longitude={ this.state.longitude } />}
        </div>
    )
}
0
Hemadri Dasari