2016-09-13 35 views
10

Xây dựng ứng dụng phản ứng nhỏ chuyển vị trí địa lý (được xác định bởi trình duyệt tới thành phần con làm đạo cụ).phản ứng đối tượng không được xác định hoặc đối tượng trống này

Thành phần đầu tiên: 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> 
    ); 
    } 
} 

thành phần này xác định vị trí, tiết kiệm dung độ và vĩ độ để nhà nước và chuyển thông tin này thông qua đạo cụ để các thành phần Weather.jsx, mà là làm việc như bạn có thể nhìn thấy trong hình dưới đây:

enter image description here

và trong thành phần weather.jsx tôi cố gắng và truy cập vào các đạo cụ và nhận được một trong hai không xác định hoặc một đối tượng rỗng.

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

Thực sự không chắc chắn vấn đề là gì với công cụ dev phản ứng cho thấy thành phần thời tiết thực sự có vị trí được đặt trong đạo cụ được chuyển xuống thành phần đó.

Sửa ** Giải Quyết:

Vì vậy, vấn đề là nhà nước được thiết lập đồng bộ và thành phần thời tiết của tôi đã được trả lại trước khi nhà nước đã được cập nhật.

Kiểm tra đơn giản các giá trị trong trạng thái trong phương thức hiển thị đã giải quyết được sự cố.

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> 
    ); 
    } 
+1

Điều gì sẽ xảy ra nếu bạn chuyển logic khởi tạo thành 'componentDidMount' thay vì' componentWillMount'. Có thể các đạo cụ chưa nhận được thành phần này vì phần tử chưa được gắn kết trong DOM. Sau khi gắn kết, sau đó thực hiện công việc. https://facebook.github.io/react/docs/component-specs.html – lux

+0

Cảm ơn vì đề xuất không may là điều đó không tạo nên sự khác biệt. Tuy nhiên tôi vừa nhận ra rằng nếu tôi chỉ trả về các đạo cụ trong hàm render, nó hoạt động và tôi thấy các đạo cụ render4ed trên trang. Vì vậy, vẫn không chắc tại sao hàm 'startApp()' không thể truy cập chúng. – chinds

Trả lời

9

Tôi tin rằng vấn đề là như sau. SetState xảy ra không đồng bộ. Bởi vì điều này, hàm render của bạn được kích hoạt trước khi các đạo cụ vĩ độ và kinh độ có dữ liệu. Nếu bạn sẽ có một số nếu kiểm tra trước khi rendering thành phần thời tiết của bạn, bạn có thể sẽ không có vấn đề này. Đây là một ví dụ về ý tôi.

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

đẹp và đơn giản như vậy, công trình này. không thể tin rằng tôi đã không nghĩ về điều này trước khi !. Cảm ơn bạn. – chinds

+1

yea điều này có thể là một gothca thực sự! –

2

Bạn cần phải ràng buộc startApp()getWeather() với thành phần, nếu không this sẽ undefined.

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); 
    } 
    ... 
} 
+0

Ok để có ý nghĩa. Với sự thay đổi này, tôi có thể truy cập các đạo cụ. tuy nhiên, các đạo cụ vĩ độ và kinh độ cho một số lý do trở lại như các chuỗi rỗng, ngay cả bây giờ các công cụ phản ứng dev cho thấy giá trị thực tế trong các đạo cụ. Vì vậy, nếu tôi 'console.log (this.props)' trong 'componentWillMount' trên trong hàm tạo tôi nhận được:' Object {latitude: "", longitude: ""} ' – chinds

+1

Bạn phải ràng buộc' startApp() ' và getLocation() 'trong thành phần' App' của bạn. – QoP

+0

Chỉ cần thực hiện điều đó và vẫn nhận được cùng một chuỗi rỗng – chinds

Các vấn đề liên quan